[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/customize/ -> class-wp-customize-header-image-setting.php (source)

   1  <?php
   2  /**
   3   * Customize API: WP_Customize_Header_Image_Setting class
   4   *
   5   * @package WordPress
   6   * @subpackage Customize
   7   * @since 4.4.0
   8   */
   9  
  10  /**
  11   * A setting that is used to filter a value, but will not save the results.
  12   *
  13   * Results should be properly handled using another setting or callback.
  14   *
  15   * @since 3.4.0
  16   *
  17   * @see WP_Customize_Setting
  18   *
  19   * @phpstan-type Header_Image_Data array{
  20   *     attachment_id?: int,
  21   *     url?: string,
  22   *     thumbnail_url?: string,
  23   *     timestamp?: int,
  24   *     width?: int,
  25   *     height?: int,
  26   *     alt_text?: string,
  27   *     attachment_parent?: int,
  28   * }
  29   */
  30  final class WP_Customize_Header_Image_Setting extends WP_Customize_Setting {
  31  
  32      /**
  33       * Unique string identifier for the setting.
  34       *
  35       * @since 3.4.0
  36       * @var string
  37       */
  38      public $id = 'header_image_data';
  39  
  40      /**
  41       * @since 3.4.0
  42       * @since 7.0.0 Return type updated from void to true for compatibility with base class.
  43       *
  44       * @global Custom_Image_Header $custom_image_header
  45       *
  46       * @param mixed $value The value to update.
  47       * @return true Always returns true.
  48       */
  49  	public function update( $value ) {
  50          global $custom_image_header;
  51  
  52          // If _custom_header_background_just_in_time() fails to initialize $custom_image_header when not is_admin().
  53          if ( empty( $custom_image_header ) ) {
  54              require_once  ABSPATH . 'wp-admin/includes/class-custom-image-header.php';
  55              $args                   = get_theme_support( 'custom-header' );
  56              $admin_head_callback    = $args[0]['admin-head-callback'] ?? null;
  57              $admin_preview_callback = $args[0]['admin-preview-callback'] ?? null;
  58              $custom_image_header    = new Custom_Image_Header( $admin_head_callback, $admin_preview_callback );
  59          }
  60  
  61          /*
  62           * If the value doesn't exist (removed or random),
  63           * use the header_image value.
  64           */
  65          if ( ! $value ) {
  66              $value = $this->manager->get_setting( 'header_image' )->post_value();
  67          }
  68  
  69          if ( is_array( $value ) && isset( $value['choice'] ) ) {
  70              $custom_image_header->set_header_image( $value['choice'] );
  71          } else {
  72              $custom_image_header->set_header_image( $value );
  73          }
  74          return true;
  75      }
  76  
  77      /**
  78       * Sanitizes a header value.
  79       *
  80       * The value is expected to be one of the following:
  81       *
  82       * - An array of header image data, with the keys `attachment_id`, `url`, `thumbnail_url`, `timestamp`, `width`,
  83       *   `height`, `alt_text`, and `attachment_parent`, as supplied by {@see get_uploaded_header_images()}. Any other
  84       *   key is discarded.
  85       * - An array with a `choice` key, being the legacy format in which any of the other accepted values is nested.
  86       * - The string `remove-header`, `random-default-image`, or `random-uploaded-image`.
  87       * - A string corresponding to one of the keys for the array returned by {@see get_uploaded_header_images()}, or
  88       *   one of the keys for the array passed into {@see register_default_headers()}.
  89       *
  90       * @since 7.1.1
  91       *
  92       * @see WP_Customize_Header_Image_Setting::update()
  93       * @see Custom_Image_Header::set_header_image()
  94       *
  95       * @param mixed $value Value to sanitize.
  96       * @return array|string|WP_Error|null Sanitized value, or `null`/`WP_Error` if invalid. The array holds
  97       *                                    the header image data, or that data nested under a `choice` key,
  98       *                                    before the `customize_sanitize_header_image_data` filter, which
  99       *                                    may return anything, is applied to it.
 100       *
 101       * @phpstan-return array<mixed, mixed>|string|WP_Error|null
 102       */
 103  	public function sanitize( $value ) {
 104          /*
 105           * The update() method unwraps the legacy `choice` format before handing the value off to
 106           * Custom_Image_Header::set_header_image(), so the nested value is what must be sanitized.
 107           */
 108          if ( is_array( $value ) && isset( $value['choice'] ) ) {
 109              $choice = $this->sanitize_choice( $value['choice'] );
 110              if ( is_null( $choice ) || is_wp_error( $choice ) ) {
 111                  return $choice;
 112              }
 113              $value = array( 'choice' => $choice );
 114          } else {
 115              $value = $this->sanitize_choice( $value );
 116              if ( is_null( $value ) || is_wp_error( $value ) ) {
 117                  return $value;
 118              }
 119          }
 120  
 121          return parent::sanitize( $value );
 122      }
 123  
 124      /**
 125       * Sanitizes a header image choice.
 126       *
 127       * This is the value which is ultimately passed to {@see Custom_Image_Header::set_header_image()}, whether
 128       * supplied at the top level of the setting value or nested under its legacy `choice` key.
 129       *
 130       * @since 7.1.1
 131       *
 132       * @param mixed $value Value to sanitize.
 133       * @return array|string|WP_Error|null Sanitized value, or `null`/`WP_Error` if invalid.
 134       *
 135       * @phpstan-return Header_Image_Data|string|WP_Error|null
 136       */
 137  	private function sanitize_choice( $value ) {
 138          // Custom_Image_Header::set_header_image() accepts an object in place of an array.
 139          if ( is_object( $value ) ) {
 140              $value = (array) $value;
 141          }
 142  
 143          if ( is_string( $value ) ) {
 144              return sanitize_text_field( $value );
 145          }
 146  
 147          if ( ! is_array( $value ) ) {
 148              return null;
 149          }
 150  
 151          /*
 152           * The sanitized value is assembled member by member rather than filtered down from the
 153           * supplied one, so that nothing but the members below can end up in it.
 154           */
 155          $sanitized = array();
 156  
 157          if ( isset( $value['attachment_id'] ) ) {
 158              if ( ! is_scalar( $value['attachment_id'] ) ) {
 159                  return null;
 160              }
 161              $attachment_id = absint( $value['attachment_id'] );
 162  
 163              /*
 164               * A supplied attachment must be an existing image, since its ID is written to postmeta and its
 165               * data displayed. Note that an ID of zero must be skipped rather than looked up, as
 166               * get_post_mime_type() falls back to the global post when passed an empty value.
 167               */
 168              if ( $attachment_id > 0 ) {
 169                  $mime_type = get_post_mime_type( $attachment_id );
 170                  if ( ! is_string( $mime_type ) || ! str_starts_with( $mime_type, 'image/' ) ) {
 171                      return null;
 172                  }
 173              }
 174  
 175              $sanitized['attachment_id'] = $attachment_id;
 176          }
 177  
 178          if ( isset( $value['url'] ) ) {
 179              if ( ! is_string( $value['url'] ) ) {
 180                  return null;
 181              }
 182              $sanitized['url'] = sanitize_url( $value['url'] );
 183              if ( '' === $sanitized['url'] ) {
 184                  return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) );
 185              }
 186          }
 187  
 188          if ( isset( $value['thumbnail_url'] ) ) {
 189              if ( ! is_string( $value['thumbnail_url'] ) ) {
 190                  return null;
 191              }
 192              $sanitized['thumbnail_url'] = sanitize_url( $value['thumbnail_url'] );
 193              if ( '' === $sanitized['thumbnail_url'] ) {
 194                  return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) );
 195              }
 196          }
 197  
 198          if ( isset( $value['timestamp'] ) ) {
 199              if ( ! is_scalar( $value['timestamp'] ) ) {
 200                  return null;
 201              }
 202              $sanitized['timestamp'] = absint( $value['timestamp'] );
 203          }
 204  
 205          if ( isset( $value['width'] ) ) {
 206              if ( ! is_scalar( $value['width'] ) ) {
 207                  return null;
 208              }
 209              $sanitized['width'] = absint( $value['width'] );
 210          }
 211  
 212          if ( isset( $value['height'] ) ) {
 213              if ( ! is_scalar( $value['height'] ) ) {
 214                  return null;
 215              }
 216              $sanitized['height'] = absint( $value['height'] );
 217          }
 218  
 219          if ( isset( $value['alt_text'] ) ) {
 220              if ( ! is_string( $value['alt_text'] ) ) {
 221                  return null;
 222              }
 223              $sanitized['alt_text'] = sanitize_text_field( $value['alt_text'] );
 224          }
 225  
 226          if ( isset( $value['attachment_parent'] ) ) {
 227              if ( ! is_scalar( $value['attachment_parent'] ) ) {
 228                  return null;
 229              }
 230              $sanitized['attachment_parent'] = absint( $value['attachment_parent'] );
 231          }
 232  
 233          return $sanitized;
 234      }
 235  }


Generated : Sat Sep 19 08:20:30 2026 Cross-referenced by PHPXref