[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/blocks/ -> search.php (source)

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


Generated: Fri Jan 21 01:00:03 2022 Cross-referenced by PHPXref 0.7.1