Title: Custom_Image_Header::step_3
Published: April 25, 2014
Last modified: April 28, 2025

---

# Custom_Image_Header::step_3()

## In this article

 * [Source](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#wp--skip-link--target)

Displays third step of custom header image page.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#source)󠁿

    ```php
    public function step_3() {
    	check_admin_referer( 'custom-header-crop-image' );

    	if ( ! current_theme_supports( 'custom-header', 'uploads' ) ) {
    		wp_die(
    			'<h1>' . __( 'An error occurred while processing your header image.' ) . '</h1>' .
    			'<p>' . __( 'The active theme does not support uploading a custom header image. Please ensure your theme supports custom headers and try again.' ) . '</p>',
    			403
    		);
    	}

    	if ( ! empty( $_POST['skip-cropping'] )
    		&& ! current_theme_supports( 'custom-header', 'flex-height' )
    		&& ! current_theme_supports( 'custom-header', 'flex-width' )
    	) {
    		wp_die(
    			'<h1>' . __( 'An error occurred while processing your header image.' ) . '</h1>' .
    			'<p>' . __( 'The active theme does not support a flexible sized header image.' ) . '</p>',
    			403
    		);
    	}

    	if ( $_POST['oitar'] > 1 ) {
    		$_POST['x1']     = $_POST['x1'] * $_POST['oitar'];
    		$_POST['y1']     = $_POST['y1'] * $_POST['oitar'];
    		$_POST['width']  = $_POST['width'] * $_POST['oitar'];
    		$_POST['height'] = $_POST['height'] * $_POST['oitar'];
    	}

    	$attachment_id = absint( $_POST['attachment_id'] );
    	$original      = get_attached_file( $attachment_id );

    	$dimensions = $this->get_header_dimensions(
    		array(
    			'height' => $_POST['height'],
    			'width'  => $_POST['width'],
    		)
    	);
    	$height     = $dimensions['dst_height'];
    	$width      = $dimensions['dst_width'];

    	if ( empty( $_POST['skip-cropping'] ) ) {
    		$cropped = wp_crop_image(
    			$attachment_id,
    			(int) $_POST['x1'],
    			(int) $_POST['y1'],
    			(int) $_POST['width'],
    			(int) $_POST['height'],
    			$width,
    			$height
    		);
    	} elseif ( ! empty( $_POST['create-new-attachment'] ) ) {
    		$cropped = _copy_image_file( $attachment_id );
    	} else {
    		$cropped = get_attached_file( $attachment_id );
    	}

    	if ( ! $cropped || is_wp_error( $cropped ) ) {
    		wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) );
    	}

    	/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
    	$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.

    	$attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, 'custom-header' );

    	if ( ! empty( $_POST['create-new-attachment'] ) ) {
    		unset( $attachment['ID'] );
    	}

    	// Update the attachment.
    	$attachment_id = $this->insert_attachment( $attachment, $cropped );

    	$url = wp_get_attachment_url( $attachment_id );
    	$this->set_header_image( compact( 'url', 'attachment_id', 'width', 'height' ) );

    	// Cleanup.
    	$medium = str_replace( wp_basename( $original ), 'midsize-' . wp_basename( $original ), $original );
    	if ( file_exists( $medium ) ) {
    		wp_delete_file( $medium );
    	}

    	if ( empty( $_POST['create-new-attachment'] ) && empty( $_POST['skip-cropping'] ) ) {
    		wp_delete_file( $original );
    	}

    	return $this->finished();
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-admin/includes/class-custom-image-header.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-admin/includes/class-custom-image-header.php#L1016)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-admin/includes/class-custom-image-header.php#L1016-L1103)

## 󠀁[Hooks](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#hooks)󠁿

 [apply_filters( ‘wp_create_file_in_uploads’, string $file, int $attachment_id )](https://developer.wordpress.org/reference/hooks/wp_create_file_in_uploads/)

Filters the attachment file path after the custom header or background image is 
set.

## 󠀁[Related](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_copy_parent_attachment_properties()](https://developer.wordpress.org/reference/functions/wp_copy_parent_attachment_properties/)`wp-admin/includes/image.php` |

Copy parent attachment properties to newly cropped image.

  | 
| [wp_delete_file()](https://developer.wordpress.org/reference/functions/wp_delete_file/)`wp-includes/functions.php` |

Deletes a file.

  | 
| [_copy_image_file()](https://developer.wordpress.org/reference/functions/_copy_image_file/)`wp-admin/includes/image.php` |

Copies an existing image file.

  | 
| [wp_crop_image()](https://developer.wordpress.org/reference/functions/wp_crop_image/)`wp-admin/includes/image.php` |

Crops an image to a given size.

  | 
| [Custom_Image_Header::get_header_dimensions()](https://developer.wordpress.org/reference/classes/custom_image_header/get_header_dimensions/)`wp-admin/includes/class-custom-image-header.php` |

Calculates width and height based on what the currently selected theme supports.

  | 
| [Custom_Image_Header::insert_attachment()](https://developer.wordpress.org/reference/classes/custom_image_header/insert_attachment/)`wp-admin/includes/class-custom-image-header.php` |

Inserts an attachment and its metadata.

  | 
| [Custom_Image_Header::set_header_image()](https://developer.wordpress.org/reference/classes/custom_image_header/set_header_image/)`wp-admin/includes/class-custom-image-header.php` |

Chooses a header image, selected from existing uploaded and default headers, or provides an array of uploaded header data (either new, or from media library).

  | 
| [Custom_Image_Header::finished()](https://developer.wordpress.org/reference/classes/custom_image_header/finished/)`wp-admin/includes/class-custom-image-header.php` |

Displays last step of custom header image page.

  | 
| [check_admin_referer()](https://developer.wordpress.org/reference/functions/check_admin_referer/)`wp-includes/pluggable.php` |

Ensures intent by verifying that a user was referred from another admin page with the correct security nonce.

  | 
| [wp_get_attachment_url()](https://developer.wordpress.org/reference/functions/wp_get_attachment_url/)`wp-includes/post.php` |

Retrieves the URL for an attachment.

  | 
| [get_attached_file()](https://developer.wordpress.org/reference/functions/get_attached_file/)`wp-includes/post.php` |

Retrieves attached file path based on attachment ID.

  | 
| [current_theme_supports()](https://developer.wordpress.org/reference/functions/current_theme_supports/)`wp-includes/theme.php` |

Checks a theme’s support for a given feature.

  | 
| [__()](https://developer.wordpress.org/reference/functions/__/)`wp-includes/l10n.php` |

Retrieves the translation of $text.

  | 
| [wp_basename()](https://developer.wordpress.org/reference/functions/wp_basename/)`wp-includes/formatting.php` |

i18n-friendly version of basename().

  | 
| [absint()](https://developer.wordpress.org/reference/functions/absint/)`wp-includes/load.php` |

Converts a value to non-negative integer.

  | 
| [wp_die()](https://developer.wordpress.org/reference/functions/wp_die/)`wp-includes/functions.php` |

Kills WordPress execution and displays HTML page with an error message.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [is_wp_error()](https://developer.wordpress.org/reference/functions/is_wp_error/)`wp-includes/load.php` |

Checks whether the given variable is a WordPress Error.

  |

[Show 13 more](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#)

| Used by | Description | 
| [Custom_Image_Header::admin_page()](https://developer.wordpress.org/reference/classes/custom_image_header/admin_page/)`wp-admin/includes/class-custom-image-header.php` |

Displays the page based on the current step.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/custom_image_header/step_3/?output_format=md#changelog)󠁿

| Version | Description | 
| [4.4.0](https://developer.wordpress.org/reference/since/4.4.0/) | Switched to using [wp_get_attachment_url()](https://developer.wordpress.org/reference/functions/wp_get_attachment_url/) instead of the guid for retrieving the header image URL. | 
| [2.1.0](https://developer.wordpress.org/reference/since/2.1.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fcustom_image_header%2Fstep_3%2F)
before being able to contribute a note or feedback.