PluginProbe
Gutenberg / 12.5.4
Gutenberg v12.5.4
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / block-library / blocks / search.php

search.php in Gutenberg 12.5.4, at build/block-library/blocks/search.php

363 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `core/search` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Dynamically renders the `core/search` block.
10 *
11 * @param array $attributes The block attributes.
12 *
13 * @return string The search block markup.
14 */
15 function gutenberg_render_block_core_search( $attributes ) {
16 static $instance_id = 0;
17
18 // Older versions of the Search block defaulted the label and buttonText
19 // attributes to `__( 'Search' )` meaning that many posts contain `<!--
20 // wp:search /-->`. Support these by defaulting an undefined label and
21 // buttonText to `__( 'Search' )`.
22 $attributes = wp_parse_args(
23 $attributes,
24 array(
25 'label' => __( 'Search' ),
26 'buttonText' => __( 'Search' ),
27 )
28 );
29
30 $input_id = 'wp-block-search__input-' . ++$instance_id;
31 $classnames = gutenberg_classnames_for_block_core_search( $attributes );
32 $show_label = ( ! empty( $attributes['showLabel'] ) ) ? true : false;
33 $use_icon_button = ( ! empty( $attributes['buttonUseIcon'] ) ) ? true : false;
34 $show_input = ( ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'] ) ? false : true;
35 $show_button = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true;
36 $input_markup = '';
37 $button_markup = '';
38 $inline_styles = gutenberg_styles_for_block_core_search( $attributes );
39 $color_classes = gutenberg_get_color_classes_for_block_core_search( $attributes );
40 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
41 'button-inside' === $attributes['buttonPosition'];
42 // Border color classes need to be applied to the elements that have a border color.
43 $border_color_classes = gutenberg_get_border_color_classes_for_block_core_search( $attributes );
44
45 $label_markup = sprintf(
46 '<label for="%1$s" class="wp-block-search__label screen-reader-text">%2$s</label>',
47 esc_attr( $input_id ),
48 empty( $attributes['label'] ) ? __( 'Search' ) : esc_html( $attributes['label'] )
49 );
50 if ( $show_label && ! empty( $attributes['label'] ) ) {
51 $label_markup = sprintf(
52 '<label for="%1$s" class="wp-block-search__label">%2$s</label>',
53 $input_id,
54 esc_html( $attributes['label'] )
55 );
56 }
57
58 if ( $show_input ) {
59 $input_classes = ! $is_button_inside ? $border_color_classes : '';
60 $input_markup = sprintf(
61 '<input type="search" id="%s" class="wp-block-search__input %s" name="s" value="%s" placeholder="%s" %s required />',
62 $input_id,
63 esc_attr( $input_classes ),
64 esc_attr( get_search_query() ),
65 esc_attr( $attributes['placeholder'] ),
66 $inline_styles['input']
67 );
68 }
69
70 if ( $show_button ) {
71 $button_internal_markup = '';
72 $button_classes = $color_classes;
73
74 if ( ! $is_button_inside ) {
75 $button_classes .= ' ' . $border_color_classes;
76 }
77 if ( ! $use_icon_button ) {
78 if ( ! empty( $attributes['buttonText'] ) ) {
79 $button_internal_markup = esc_html( $attributes['buttonText'] );
80 }
81 } else {
82 $button_classes .= ' has-icon';
83 $button_internal_markup =
84 '<svg id="search-icon" class="search-icon" viewBox="0 0 24 24" width="24" height="24">
85 <path d="M13.5 6C10.5 6 8 8.5 8 11.5c0 1.1.3 2.1.9 3l-3.4 3 1 1.1 3.4-2.9c1 .9 2.2 1.4 3.6 1.4 3 0 5.5-2.5 5.5-5.5C19 8.5 16.5 6 13.5 6zm0 9.5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"></path>
86 </svg>';
87 }
88
89 $button_markup = sprintf(
90 '<button type="submit" class="wp-block-search__button %s" %s>%s</button>',
91 esc_attr( $button_classes ),
92 $inline_styles['button'],
93 $button_internal_markup
94 );
95 }
96
97 $field_markup_classes = $is_button_inside ? $border_color_classes : '';
98 $field_markup = sprintf(
99 '<div class="wp-block-search__inside-wrapper %s" %s>%s</div>',
100 esc_attr( $field_markup_classes ),
101 $inline_styles['wrapper'],
102 $input_markup . $button_markup
103 );
104 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
105
106 return sprintf(
107 '<form role="search" method="get" action="%s" %s>%s</form>',
108 esc_url( home_url( '/' ) ),
109 $wrapper_attributes,
110 $label_markup . $field_markup
111 );
112 }
113
114 /**
115 * Registers the `core/search` block on the server.
116 */
117 function gutenberg_register_block_core_search() {
118 register_block_type_from_metadata(
119 __DIR__ . '/search',
120 array(
121 'render_callback' => 'gutenberg_render_block_core_search',
122 )
123 );
124 }
125 add_action( 'init', 'gutenberg_register_block_core_search', 20 );
126
127 /**
128 * Builds the correct top level classnames for the 'core/search' block.
129 *
130 * @param array $attributes The block attributes.
131 *
132 * @return string The classnames used in the block.
133 */
134 function gutenberg_classnames_for_block_core_search( $attributes ) {
135 $classnames = array();
136
137 if ( ! empty( $attributes['buttonPosition'] ) ) {
138 if ( 'button-inside' === $attributes['buttonPosition'] ) {
139 $classnames[] = 'wp-block-search__button-inside';
140 }
141
142 if ( 'button-outside' === $attributes['buttonPosition'] ) {
143 $classnames[] = 'wp-block-search__button-outside';
144 }
145
146 if ( 'no-button' === $attributes['buttonPosition'] ) {
147 $classnames[] = 'wp-block-search__no-button';
148 }
149
150 if ( 'button-only' === $attributes['buttonPosition'] ) {
151 $classnames[] = 'wp-block-search__button-only';
152 }
153 }
154
155 if ( isset( $attributes['buttonUseIcon'] ) ) {
156 if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
157 if ( $attributes['buttonUseIcon'] ) {
158 $classnames[] = 'wp-block-search__icon-button';
159 } else {
160 $classnames[] = 'wp-block-search__text-button';
161 }
162 }
163 }
164
165 return implode( ' ', $classnames );
166 }
167
168 /**
169 * Builds an array of inline styles for the search block.
170 *
171 * The result will contain one entry for shared styles such as those for the
172 * inner input or button and a second for the inner wrapper should the block
173 * be positioning the button "inside".
174 *
175 * @param array $attributes The block attributes.
176 *
177 * @return array Style HTML attribute.
178 */
179 function gutenberg_styles_for_block_core_search( $attributes ) {
180 $wrapper_styles = array();
181 $button_styles = array();
182 $input_styles = array();
183 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
184 'button-inside' === $attributes['buttonPosition'];
185
186 // Add width styles.
187 $has_width = ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] );
188 $button_only = ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'];
189
190 if ( $has_width && ! $button_only ) {
191 $wrapper_styles[] = sprintf(
192 'width: %d%s;',
193 esc_attr( $attributes['width'] ),
194 esc_attr( $attributes['widthUnit'] )
195 );
196 }
197
198 // Add border width styles.
199 $has_border_width = ! empty( $attributes['style']['border']['width'] );
200
201 if ( $has_border_width ) {
202 $border_width = $attributes['style']['border']['width'];
203
204 if ( $is_button_inside ) {
205 $wrapper_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
206 } else {
207 $button_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
208 $input_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
209 }
210 }
211
212 // Add border radius styles.
213 $has_border_radius = ! empty( $attributes['style']['border']['radius'] );
214
215 if ( $has_border_radius ) {
216 $default_padding = '4px';
217 $border_radius = $attributes['style']['border']['radius'];
218
219 if ( is_array( $border_radius ) ) {
220 // Apply styles for individual corner border radii.
221 foreach ( $border_radius as $key => $value ) {
222 if ( null !== $value ) {
223 // Convert camelCase key to kebab-case.
224 $name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
225
226 // Add shared styles for individual border radii for input & button.
227 $border_style = sprintf(
228 'border-%s-radius: %s;',
229 esc_attr( $name ),
230 esc_attr( $value )
231 );
232 $input_styles[] = $border_style;
233 $button_styles[] = $border_style;
234
235 // Add adjusted border radius styles for the wrapper element
236 // if button is positioned inside.
237 if ( $is_button_inside && intval( $value ) !== 0 ) {
238 $wrapper_styles[] = sprintf(
239 'border-%s-radius: calc(%s + %s);',
240 esc_attr( $name ),
241 esc_attr( $value ),
242 $default_padding
243 );
244 }
245 }
246 }
247 } else {
248 // Numeric check is for backwards compatibility purposes.
249 $border_radius = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
250 $border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
251 $input_styles[] = $border_style;
252 $button_styles[] = $border_style;
253
254 if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
255 // Adjust wrapper border radii to maintain visual consistency
256 // with inner elements when button is positioned inside.
257 $wrapper_styles[] = sprintf(
258 'border-radius: calc(%s + %s);',
259 esc_attr( $border_radius ),
260 $default_padding
261 );
262 }
263 }
264 }
265
266 // Add border color styles.
267 $has_border_color = ! empty( $attributes['style']['border']['color'] );
268
269 if ( $has_border_color ) {
270 $border_color = $attributes['style']['border']['color'];
271
272 // Apply wrapper border color if button placed inside.
273 if ( $is_button_inside ) {
274 $wrapper_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
275 } else {
276 $button_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
277 $input_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
278 }
279 }
280
281 // Add color styles.
282 $has_text_color = ! empty( $attributes['style']['color']['text'] );
283 if ( $has_text_color ) {
284 $button_styles[] = sprintf( 'color: %s;', esc_attr( $attributes['style']['color']['text'] ) );
285 }
286
287 $has_background_color = ! empty( $attributes['style']['color']['background'] );
288 if ( $has_background_color ) {
289 $button_styles[] = sprintf( 'background-color: %s;', esc_attr( $attributes['style']['color']['background'] ) );
290 }
291
292 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
293 if ( $has_custom_gradient ) {
294 $button_styles[] = sprintf( 'background: %s;', $attributes['style']['color']['gradient'] );
295 }
296
297 return array(
298 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $input_styles ) ) ) : '',
299 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $button_styles ) ) ) : '',
300 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $wrapper_styles ) ) ) : '',
301 );
302 }
303
304 /**
305 * Returns border color classnames depending on whether there are named or custom border colors.
306 *
307 * @param array $attributes The block attributes.
308 *
309 * @return string The border color classnames to be applied to the block elements.
310 */
311 function gutenberg_get_border_color_classes_for_block_core_search( $attributes ) {
312 $has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
313 $border_color_classes = ! empty( $attributes['borderColor'] ) ? sprintf( 'has-border-color has-%s-border-color', $attributes['borderColor'] ) : '';
314 // If there's a border color style and no `borderColor` text string, we still want to add the generic `has-border-color` class name to the element.
315 if ( $has_custom_border_color && empty( $attributes['borderColor'] ) ) {
316 $border_color_classes = 'has-border-color';
317 }
318 return $border_color_classes;
319 }
320
321 /**
322 * Returns color classnames depending on whether there are named or custom text and background colors.
323 *
324 * @param array $attributes The block attributes.
325 *
326 * @return string The color classnames to be applied to the block elements.
327 */
328 function gutenberg_get_color_classes_for_block_core_search( $attributes ) {
329 $classnames = array();
330
331 // Text color.
332 $has_named_text_color = ! empty( $attributes['textColor'] );
333 $has_custom_text_color = ! empty( $attributes['style']['color']['text'] );
334 if ( $has_named_text_color ) {
335 $classnames[] = sprintf( 'has-text-color has-%s-color', $attributes['textColor'] );
336 } elseif ( $has_custom_text_color ) {
337 // If a custom 'textColor' was selected instead of a preset, still add the generic `has-text-color` class.
338 $classnames[] = 'has-text-color';
339 }
340
341 // Background color.
342 $has_named_background_color = ! empty( $attributes['backgroundColor'] );
343 $has_custom_background_color = ! empty( $attributes['style']['color']['background'] );
344 $has_named_gradient = ! empty( $attributes['gradient'] );
345 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
346 if (
347 $has_named_background_color ||
348 $has_custom_background_color ||
349 $has_named_gradient ||
350 $has_custom_gradient
351 ) {
352 $classnames[] = 'has-background';
353 }
354 if ( $has_named_background_color ) {
355 $classnames[] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
356 }
357 if ( $has_named_gradient ) {
358 $classnames[] = sprintf( 'has-%s-gradient-background', $attributes['gradient'] );
359 }
360
361 return implode( ' ', $classnames );
362 }
363