Edit File by line
/home/zeestwma/richards.../wp-inclu.../blocks
File: image.php
<?php
[0] Fix | Delete
/**
[1] Fix | Delete
* Server-side rendering of the `core/image` block.
[2] Fix | Delete
*
[3] Fix | Delete
* @package WordPress
[4] Fix | Delete
*/
[5] Fix | Delete
[6] Fix | Delete
/**
[7] Fix | Delete
* Renders the `core/image` block on the server,
[8] Fix | Delete
* adding a data-id attribute to the element if core/gallery has added on pre-render.
[9] Fix | Delete
*
[10] Fix | Delete
* @since 5.9.0
[11] Fix | Delete
*
[12] Fix | Delete
* @param array $attributes The block attributes.
[13] Fix | Delete
* @param string $content The block content.
[14] Fix | Delete
* @param WP_Block $block The block object.
[15] Fix | Delete
*
[16] Fix | Delete
* @return string The block content with the data-id attribute added.
[17] Fix | Delete
*/
[18] Fix | Delete
function render_block_core_image( $attributes, $content, $block ) {
[19] Fix | Delete
if ( false === stripos( $content, '<img' ) ) {
[20] Fix | Delete
return '';
[21] Fix | Delete
}
[22] Fix | Delete
[23] Fix | Delete
$p = new WP_HTML_Tag_Processor( $content );
[24] Fix | Delete
[25] Fix | Delete
if ( ! $p->next_tag( 'img' ) || null === $p->get_attribute( 'src' ) ) {
[26] Fix | Delete
return '';
[27] Fix | Delete
}
[28] Fix | Delete
[29] Fix | Delete
$has_id_binding = isset( $attributes['metadata']['bindings']['id'] ) && isset( $attributes['id'] );
[30] Fix | Delete
[31] Fix | Delete
// Ensure the `wp-image-id` classname on the image block supports block bindings.
[32] Fix | Delete
if ( $has_id_binding ) {
[33] Fix | Delete
// If there's a mismatch with the 'wp-image-' class and the actual id, the id was
[34] Fix | Delete
// probably overridden by block bindings. Update it to the correct value.
[35] Fix | Delete
// See https://github.com/WordPress/gutenberg/issues/62886 for why this is needed.
[36] Fix | Delete
$id = $attributes['id'];
[37] Fix | Delete
$image_classnames = $p->get_attribute( 'class' );
[38] Fix | Delete
$class_with_binding_value = "wp-image-$id";
[39] Fix | Delete
if ( is_string( $image_classnames ) && ! str_contains( $image_classnames, $class_with_binding_value ) ) {
[40] Fix | Delete
$image_classnames = preg_replace( '/wp-image-(\d+)/', $class_with_binding_value, $image_classnames );
[41] Fix | Delete
$p->set_attribute( 'class', $image_classnames );
[42] Fix | Delete
}
[43] Fix | Delete
}
[44] Fix | Delete
[45] Fix | Delete
// For backwards compatibility, the data-id html attribute is only set for
[46] Fix | Delete
// image blocks nested in a gallery. Detect if the image is in a gallery by
[47] Fix | Delete
// checking the data-id attribute.
[48] Fix | Delete
// See the `block_core_gallery_data_id_backcompatibility` function.
[49] Fix | Delete
if ( isset( $attributes['data-id'] ) ) {
[50] Fix | Delete
// If there's a binding for the `id`, the `id` attribute is used for the
[51] Fix | Delete
// value, since `data-id` does not support block bindings.
[52] Fix | Delete
// Else the `data-id` is used for backwards compatibility, since
[53] Fix | Delete
// third parties may be filtering its value.
[54] Fix | Delete
$data_id = $has_id_binding ? $attributes['id'] : $attributes['data-id'];
[55] Fix | Delete
$p->set_attribute( 'data-id', $data_id );
[56] Fix | Delete
}
[57] Fix | Delete
[58] Fix | Delete
$link_destination = isset( $attributes['linkDestination'] ) ? $attributes['linkDestination'] : 'none';
[59] Fix | Delete
$lightbox_settings = block_core_image_get_lightbox_settings( $block->parsed_block );
[60] Fix | Delete
[61] Fix | Delete
/*
[62] Fix | Delete
* If the lightbox is enabled and the image is not linked, adds the filter and
[63] Fix | Delete
* the JavaScript view file.
[64] Fix | Delete
*/
[65] Fix | Delete
if (
[66] Fix | Delete
isset( $lightbox_settings ) &&
[67] Fix | Delete
'none' === $link_destination &&
[68] Fix | Delete
isset( $lightbox_settings['enabled'] ) &&
[69] Fix | Delete
true === $lightbox_settings['enabled']
[70] Fix | Delete
) {
[71] Fix | Delete
$suffix = wp_scripts_get_suffix();
[72] Fix | Delete
if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
[73] Fix | Delete
$module_url = gutenberg_url( '/build/interactivity/image.min.js' );
[74] Fix | Delete
}
[75] Fix | Delete
[76] Fix | Delete
wp_register_script_module(
[77] Fix | Delete
'@wordpress/block-library/image',
[78] Fix | Delete
isset( $module_url ) ? $module_url : includes_url( "blocks/image/view{$suffix}.js" ),
[79] Fix | Delete
array( '@wordpress/interactivity' ),
[80] Fix | Delete
defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
[81] Fix | Delete
);
[82] Fix | Delete
[83] Fix | Delete
wp_enqueue_script_module( '@wordpress/block-library/image' );
[84] Fix | Delete
[85] Fix | Delete
/*
[86] Fix | Delete
* This render needs to happen in a filter with priority 15 to ensure that
[87] Fix | Delete
* it runs after the duotone filter and that duotone styles are applied to
[88] Fix | Delete
* the image in the lightbox. Lightbox has to work with any plugins that
[89] Fix | Delete
* might use filters as well. Removing this can be considered in the future
[90] Fix | Delete
* if the way the blocks are rendered changes, or if a new kind of filter is
[91] Fix | Delete
* introduced.
[92] Fix | Delete
*/
[93] Fix | Delete
add_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15, 2 );
[94] Fix | Delete
} else {
[95] Fix | Delete
/*
[96] Fix | Delete
* Remove the filter if previously added by other Image blocks.
[97] Fix | Delete
*/
[98] Fix | Delete
remove_filter( 'render_block_core/image', 'block_core_image_render_lightbox', 15 );
[99] Fix | Delete
}
[100] Fix | Delete
[101] Fix | Delete
return $p->get_updated_html();
[102] Fix | Delete
}
[103] Fix | Delete
[104] Fix | Delete
/**
[105] Fix | Delete
* Adds the lightboxEnabled flag to the block data.
[106] Fix | Delete
*
[107] Fix | Delete
* This is used to determine whether the lightbox should be rendered or not.
[108] Fix | Delete
*
[109] Fix | Delete
* @since 6.4.0
[110] Fix | Delete
*
[111] Fix | Delete
* @param array $block Block data.
[112] Fix | Delete
*
[113] Fix | Delete
* @return array Filtered block data.
[114] Fix | Delete
*/
[115] Fix | Delete
function block_core_image_get_lightbox_settings( $block ) {
[116] Fix | Delete
// Gets the lightbox setting from the block attributes.
[117] Fix | Delete
if ( isset( $block['attrs']['lightbox'] ) ) {
[118] Fix | Delete
$lightbox_settings = $block['attrs']['lightbox'];
[119] Fix | Delete
}
[120] Fix | Delete
[121] Fix | Delete
if ( ! isset( $lightbox_settings ) ) {
[122] Fix | Delete
$lightbox_settings = wp_get_global_settings( array( 'lightbox' ), array( 'block_name' => 'core/image' ) );
[123] Fix | Delete
[124] Fix | Delete
// If not present in global settings, check the top-level global settings.
[125] Fix | Delete
//
[126] Fix | Delete
// NOTE: If no block-level settings are found, the previous call to
[127] Fix | Delete
// `wp_get_global_settings` will return the whole `theme.json` structure in
[128] Fix | Delete
// which case we can check if the "lightbox" key is present at the top-level
[129] Fix | Delete
// of the global settings and use its value.
[130] Fix | Delete
if ( isset( $lightbox_settings['lightbox'] ) ) {
[131] Fix | Delete
$lightbox_settings = wp_get_global_settings( array( 'lightbox' ) );
[132] Fix | Delete
}
[133] Fix | Delete
}
[134] Fix | Delete
[135] Fix | Delete
return $lightbox_settings ?? null;
[136] Fix | Delete
}
[137] Fix | Delete
[138] Fix | Delete
/**
[139] Fix | Delete
* Adds the directives and layout needed for the lightbox behavior.
[140] Fix | Delete
*
[141] Fix | Delete
* @since 6.4.0
[142] Fix | Delete
*
[143] Fix | Delete
* @param string $block_content Rendered block content.
[144] Fix | Delete
* @param array $block Block object.
[145] Fix | Delete
*
[146] Fix | Delete
* @return string Filtered block content.
[147] Fix | Delete
*/
[148] Fix | Delete
function block_core_image_render_lightbox( $block_content, $block ) {
[149] Fix | Delete
/*
[150] Fix | Delete
* If there's no IMG tag in the block then return the given block content
[151] Fix | Delete
* as-is. There's nothing that this code can knowingly modify to add the
[152] Fix | Delete
* lightbox behavior.
[153] Fix | Delete
*/
[154] Fix | Delete
$p = new WP_HTML_Tag_Processor( $block_content );
[155] Fix | Delete
if ( $p->next_tag( 'figure' ) ) {
[156] Fix | Delete
$p->set_bookmark( 'figure' );
[157] Fix | Delete
}
[158] Fix | Delete
if ( ! $p->next_tag( 'img' ) ) {
[159] Fix | Delete
return $block_content;
[160] Fix | Delete
}
[161] Fix | Delete
[162] Fix | Delete
$alt = $p->get_attribute( 'alt' );
[163] Fix | Delete
$img_uploaded_src = $p->get_attribute( 'src' );
[164] Fix | Delete
$img_class_names = $p->get_attribute( 'class' );
[165] Fix | Delete
$img_styles = $p->get_attribute( 'style' );
[166] Fix | Delete
$img_width = 'none';
[167] Fix | Delete
$img_height = 'none';
[168] Fix | Delete
$aria_label = __( 'Enlarge image' );
[169] Fix | Delete
[170] Fix | Delete
if ( $alt ) {
[171] Fix | Delete
/* translators: %s: Image alt text. */
[172] Fix | Delete
$aria_label = sprintf( __( 'Enlarge image: %s' ), $alt );
[173] Fix | Delete
}
[174] Fix | Delete
[175] Fix | Delete
if ( isset( $block['attrs']['id'] ) ) {
[176] Fix | Delete
$img_uploaded_src = wp_get_attachment_url( $block['attrs']['id'] );
[177] Fix | Delete
$img_metadata = wp_get_attachment_metadata( $block['attrs']['id'] );
[178] Fix | Delete
$img_width = $img_metadata['width'] ?? 'none';
[179] Fix | Delete
$img_height = $img_metadata['height'] ?? 'none';
[180] Fix | Delete
}
[181] Fix | Delete
[182] Fix | Delete
// Figure.
[183] Fix | Delete
$p->seek( 'figure' );
[184] Fix | Delete
$figure_class_names = $p->get_attribute( 'class' );
[185] Fix | Delete
$figure_styles = $p->get_attribute( 'style' );
[186] Fix | Delete
$p->add_class( 'wp-lightbox-container' );
[187] Fix | Delete
$p->set_attribute( 'data-wp-interactive', 'core/image' );
[188] Fix | Delete
$p->set_attribute(
[189] Fix | Delete
'data-wp-context',
[190] Fix | Delete
wp_json_encode(
[191] Fix | Delete
array(
[192] Fix | Delete
'uploadedSrc' => $img_uploaded_src,
[193] Fix | Delete
'figureClassNames' => $figure_class_names,
[194] Fix | Delete
'figureStyles' => $figure_styles,
[195] Fix | Delete
'imgClassNames' => $img_class_names,
[196] Fix | Delete
'imgStyles' => $img_styles,
[197] Fix | Delete
'targetWidth' => $img_width,
[198] Fix | Delete
'targetHeight' => $img_height,
[199] Fix | Delete
'scaleAttr' => $block['attrs']['scale'] ?? false,
[200] Fix | Delete
'ariaLabel' => $aria_label,
[201] Fix | Delete
'alt' => $alt,
[202] Fix | Delete
),
[203] Fix | Delete
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
[204] Fix | Delete
)
[205] Fix | Delete
);
[206] Fix | Delete
[207] Fix | Delete
// Image.
[208] Fix | Delete
$p->next_tag( 'img' );
[209] Fix | Delete
$p->set_attribute( 'data-wp-init', 'callbacks.setButtonStyles' );
[210] Fix | Delete
$p->set_attribute( 'data-wp-on-async--load', 'callbacks.setButtonStyles' );
[211] Fix | Delete
$p->set_attribute( 'data-wp-on-async-window--resize', 'callbacks.setButtonStyles' );
[212] Fix | Delete
// Sets an event callback on the `img` because the `figure` element can also
[213] Fix | Delete
// contain a caption, and we don't want to trigger the lightbox when the
[214] Fix | Delete
// caption is clicked.
[215] Fix | Delete
$p->set_attribute( 'data-wp-on-async--click', 'actions.showLightbox' );
[216] Fix | Delete
[217] Fix | Delete
$body_content = $p->get_updated_html();
[218] Fix | Delete
[219] Fix | Delete
// Adds a button alongside image in the body content.
[220] Fix | Delete
$img = null;
[221] Fix | Delete
preg_match( '/<img[^>]+>/', $body_content, $img );
[222] Fix | Delete
[223] Fix | Delete
$button =
[224] Fix | Delete
$img[0]
[225] Fix | Delete
. '<button
[226] Fix | Delete
class="lightbox-trigger"
[227] Fix | Delete
type="button"
[228] Fix | Delete
aria-haspopup="dialog"
[229] Fix | Delete
aria-label="' . esc_attr( $aria_label ) . '"
[230] Fix | Delete
data-wp-init="callbacks.initTriggerButton"
[231] Fix | Delete
data-wp-on-async--click="actions.showLightbox"
[232] Fix | Delete
data-wp-style--right="context.imageButtonRight"
[233] Fix | Delete
data-wp-style--top="context.imageButtonTop"
[234] Fix | Delete
>
[235] Fix | Delete
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
[236] Fix | Delete
<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
[237] Fix | Delete
</svg>
[238] Fix | Delete
</button>';
[239] Fix | Delete
[240] Fix | Delete
$body_content = preg_replace( '/<img[^>]+>/', $button, $body_content );
[241] Fix | Delete
[242] Fix | Delete
add_action( 'wp_footer', 'block_core_image_print_lightbox_overlay' );
[243] Fix | Delete
[244] Fix | Delete
return $body_content;
[245] Fix | Delete
}
[246] Fix | Delete
[247] Fix | Delete
/**
[248] Fix | Delete
* @since 6.5.0
[249] Fix | Delete
*/
[250] Fix | Delete
function block_core_image_print_lightbox_overlay() {
[251] Fix | Delete
$close_button_label = esc_attr__( 'Close' );
[252] Fix | Delete
[253] Fix | Delete
// If the current theme does NOT have a `theme.json`, or the colors are not
[254] Fix | Delete
// defined, it needs to set the background color & close button color to some
[255] Fix | Delete
// default values because it can't get them from the Global Styles.
[256] Fix | Delete
$background_color = '#fff';
[257] Fix | Delete
$close_button_color = '#000';
[258] Fix | Delete
if ( wp_theme_has_theme_json() ) {
[259] Fix | Delete
$global_styles_color = wp_get_global_styles( array( 'color' ) );
[260] Fix | Delete
if ( ! empty( $global_styles_color['background'] ) ) {
[261] Fix | Delete
$background_color = esc_attr( $global_styles_color['background'] );
[262] Fix | Delete
}
[263] Fix | Delete
if ( ! empty( $global_styles_color['text'] ) ) {
[264] Fix | Delete
$close_button_color = esc_attr( $global_styles_color['text'] );
[265] Fix | Delete
}
[266] Fix | Delete
}
[267] Fix | Delete
[268] Fix | Delete
echo <<<HTML
[269] Fix | Delete
<div
[270] Fix | Delete
class="wp-lightbox-overlay zoom"
[271] Fix | Delete
data-wp-interactive="core/image"
[272] Fix | Delete
data-wp-context='{}'
[273] Fix | Delete
data-wp-bind--role="state.roleAttribute"
[274] Fix | Delete
data-wp-bind--aria-label="state.currentImage.ariaLabel"
[275] Fix | Delete
data-wp-bind--aria-modal="state.ariaModal"
[276] Fix | Delete
data-wp-class--active="state.overlayEnabled"
[277] Fix | Delete
data-wp-class--show-closing-animation="state.showClosingAnimation"
[278] Fix | Delete
data-wp-watch="callbacks.setOverlayFocus"
[279] Fix | Delete
data-wp-on--keydown="actions.handleKeydown"
[280] Fix | Delete
data-wp-on-async--touchstart="actions.handleTouchStart"
[281] Fix | Delete
data-wp-on--touchmove="actions.handleTouchMove"
[282] Fix | Delete
data-wp-on-async--touchend="actions.handleTouchEnd"
[283] Fix | Delete
data-wp-on-async--click="actions.hideLightbox"
[284] Fix | Delete
data-wp-on-async-window--resize="callbacks.setOverlayStyles"
[285] Fix | Delete
data-wp-on-async-window--scroll="actions.handleScroll"
[286] Fix | Delete
tabindex="-1"
[287] Fix | Delete
>
[288] Fix | Delete
<button type="button" aria-label="$close_button_label" style="fill: $close_button_color" class="close-button">
[289] Fix | Delete
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>
[290] Fix | Delete
</button>
[291] Fix | Delete
<div class="lightbox-image-container">
[292] Fix | Delete
<figure data-wp-bind--class="state.currentImage.figureClassNames" data-wp-bind--style="state.currentImage.figureStyles">
[293] Fix | Delete
<img data-wp-bind--alt="state.currentImage.alt" data-wp-bind--class="state.currentImage.imgClassNames" data-wp-bind--style="state.imgStyles" data-wp-bind--src="state.currentImage.currentSrc">
[294] Fix | Delete
</figure>
[295] Fix | Delete
</div>
[296] Fix | Delete
<div class="lightbox-image-container">
[297] Fix | Delete
<figure data-wp-bind--class="state.currentImage.figureClassNames" data-wp-bind--style="state.currentImage.figureStyles">
[298] Fix | Delete
<img data-wp-bind--alt="state.currentImage.alt" data-wp-bind--class="state.currentImage.imgClassNames" data-wp-bind--style="state.imgStyles" data-wp-bind--src="state.enlargedSrc">
[299] Fix | Delete
</figure>
[300] Fix | Delete
</div>
[301] Fix | Delete
<div class="scrim" style="background-color: $background_color" aria-hidden="true"></div>
[302] Fix | Delete
<style data-wp-text="state.overlayStyles"></style>
[303] Fix | Delete
</div>
[304] Fix | Delete
HTML;
[305] Fix | Delete
}
[306] Fix | Delete
[307] Fix | Delete
/**
[308] Fix | Delete
* Registers the `core/image` block on server.
[309] Fix | Delete
*
[310] Fix | Delete
* @since 5.9.0
[311] Fix | Delete
*/
[312] Fix | Delete
function register_block_core_image() {
[313] Fix | Delete
register_block_type_from_metadata(
[314] Fix | Delete
__DIR__ . '/image',
[315] Fix | Delete
array(
[316] Fix | Delete
'render_callback' => 'render_block_core_image',
[317] Fix | Delete
)
[318] Fix | Delete
);
[319] Fix | Delete
}
[320] Fix | Delete
add_action( 'init', 'register_block_core_image' );
[321] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function