: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Updates the last-used postmeta on a header image attachment after saving a new header image via the Customizer.
* @param WP_Customize_Manager $wp_customize Customize manager.
public function customize_set_last_used( $wp_customize ) {
$header_image_data_setting = $wp_customize->get_setting( 'header_image_data' );
if ( ! $header_image_data_setting ) {
$data = $header_image_data_setting->post_value();
if ( ! isset( $data['attachment_id'] ) ) {
$attachment_id = $data['attachment_id'];
$key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
update_post_meta( $attachment_id, $key, time() );
* Gets the details of default header images if defined.
* @return array Default header images.
public function get_default_header_images() {
$this->process_default_headers();
// Get the default image if there is one.
$default = get_theme_support( 'custom-header', 'default-image' );
if ( ! $default ) { // If not, easy peasy.
return $this->default_headers;
$default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() );
$already_has_default = false;
foreach ( $this->default_headers as $k => $h ) {
if ( $h['url'] === $default ) {
$already_has_default = true;
if ( $already_has_default ) {
return $this->default_headers;
// If the one true image isn't included in the default set, prepend it.
$header_images = array();
$header_images['default'] = array(
'thumbnail_url' => $default,
'description' => 'Default',
// The rest of the set comes after.
return array_merge( $header_images, $this->default_headers );
* Gets the previously uploaded header images.
* @return array Uploaded header images.
public function get_uploaded_header_images() {
$header_images = get_uploaded_header_images();
$timestamp_key = '_wp_attachment_custom_header_last_used_' . get_stylesheet();
$alt_text_key = '_wp_attachment_image_alt';
foreach ( $header_images as &$header_image ) {
$header_meta = get_post_meta( $header_image['attachment_id'] );
$header_image['timestamp'] = isset( $header_meta[ $timestamp_key ] ) ? $header_meta[ $timestamp_key ] : '';
$header_image['alt_text'] = isset( $header_meta[ $alt_text_key ] ) ? $header_meta[ $alt_text_key ] : '';
* Gets the ID of a previous crop from the same base image.
* @param array $attachment An array with a cropped attachment object data.
* @return int|false An attachment ID if one exists. False if none.
public function get_previous_crop( $attachment ) {
$header_images = $this->get_uploaded_header_images();
// Bail early if there are no header images.
if ( empty( $header_images ) ) {
foreach ( $header_images as $image ) {
if ( $image['attachment_parent'] === $attachment['post_parent'] ) {
$previous = $image['attachment_id'];