Index: wp-admin/includes/admin.php
===================================================================
--- wp-admin/includes/admin.php	(revision 33173)
+++ wp-admin/includes/admin.php	(working copy)
@@ -66,6 +66,8 @@
 
 /** WordPress Site Icon API */
 require_once(ABSPATH . 'wp-admin/includes/class-wp-site-icon.php');
+require_once(ABSPATH . 'wp-admin/includes/class-wp-site-icon-admin-processing.php');
+require_once(ABSPATH . 'wp-admin/includes/class-wp-site-icon-admin-ui.php');
 
 /** WordPress Update Administration API */
 require_once(ABSPATH . 'wp-admin/includes/update.php');
Index: wp-admin/includes/class-wp-site-icon-admin-processing.php
===================================================================
--- wp-admin/includes/class-wp-site-icon-admin-processing.php	(revision 0)
+++ wp-admin/includes/class-wp-site-icon-admin-processing.php	(working copy)
@@ -0,0 +1,323 @@
+<?php
+
+class WP_Site_Icon_Admin_Processing {
+	public function __construct() {
+
+		add_action( 'delete_attachment', array( $this, 'delete_attachment_data' ), 10, 1 );
+		add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 );
+	}
+
+	/**
+	 * Upload a Site Icon image.
+	 *
+	 * This method is only used by the no Javascript admin UI flow.
+	 *
+	 * @since 4.3.0
+	 */
+	public function upload_site_icon_image() {
+		// Verify that the uploaded file is an image.
+		$file_type = wp_check_filetype_and_ext( $_FILES['site-icon']['tmp_name'], $_FILES['site-icon']['name'] );
+		if ( ! wp_match_mime_types( 'image', $file_type['type'] ) ) {
+			wp_die( __( 'The uploaded file is not a valid image. Please try again.' ) );
+		}
+
+		// Upload image.
+		$file_attributes = wp_handle_upload( $_FILES['site-icon'], array( 'test_form' => false ) );
+		if ( isset( $file_attributes['error'] ) ) {
+			wp_die( $file_attributes['error'], __( 'Image Upload Error' ) );
+		}
+
+		// Save image as an attachment.
+		$attachment_id = wp_insert_attachment( array(
+			'post_title'     => basename( $file_attributes['file'] ),
+			'post_content'   => $file_attributes['url'],
+			'post_mime_type' => $file_attributes['type'],
+			'guid'           => $file_attributes['url'],
+			'context'        => 'site-icon',
+		),
+			$file_attributes['file'] );
+
+		if ( 0 === $attachment_id || is_wp_error( $attachment_id ) ) {
+			wp_die( __( 'Could not save the uploaded image.' ) );
+		}
+
+		return $attachment_id;
+	}
+
+	public function get_image_size_from_attachment( $attachment_id ) {
+		$image_file = get_attached_file( absint( $attachment_id ), true );
+
+		if ( ! $image_file ) {
+			wp_die( __( 'The uploaded image is corrupted.' ) );
+		}
+
+		return getimagesize( $image_file );
+	}
+
+	/**
+	 * Checks whether the uploaded image is large enough to be a Site Icon.
+	 *
+	 * @param int $attachment_id ID of the attachment containing the image.
+	 * @param int $min_width     Minimum width in pixels.
+	 * @param int $min_height    Minimum height in pixels.
+	 *
+	 * @return bool|array True if the image is large enough. An array with the errors if the image is too small.
+	 */
+	public function verify_site_icon_image_min_size( $attachment_id, $min_width, $min_height ) {
+		$image_file = get_attached_file( absint( $attachment_id ), true );
+
+		if ( ! $image_file ) {
+			wp_die( __( 'The uploaded image is corrupted.' ) );
+		}
+
+		$image_size = getimagesize( $image_file );
+
+		$errors = array();
+		if ( $image_size[0] < $min_width ) {
+			$errors['width'] = true;
+		}
+
+		if ( $image_size[1] < $min_height ) {
+			$errors['height'] = true;
+		}
+
+		if ( $errors ) {
+			return $errors;
+		}
+
+		return true;
+	}
+
+	public function get_attachment_image_size( $attachment_id ) {
+		$image_file = get_attached_file( absint( $attachment_id ), true );
+
+		if ( ! $image_file ) {
+			wp_die( __( 'The uploaded image is corrupted.' ) );
+		}
+
+		return getimagesize( $image_file );
+	}
+
+	public function get_site_icon_image_url( $attachment_id ) {
+		$image_data = wp_get_attachment_image_src( $attachment_id, 'full' );
+
+		if ( ! $image_data ) {
+			return false;
+		}
+
+		return $image_data[0];
+	}
+
+	/**
+	 * Calculate the size of the image displayed on the cropping screen.
+	 *
+	 * @param $attachment_id
+	 * @param $max_size
+	 */
+	public function calculate_height_of_image_for_cropping( $attachment_id, $max_width ) {
+		// Get the size of the full image.
+		$full_size = $this->get_attachment_image_size( absint( $attachment_id ) );
+
+		// Calculate the relationship between the height and the width of the full image.
+		$ratio = $full_size[1] / $full_size[0];
+
+		// Multiply the max width of the image in the admin to get the correct height to keeping the ratio intact.
+		return (int) floor( $max_width * $ratio );
+	}
+
+	public function calculate_default_values_for_crop( $width, $height ) {
+		if ( $width < $height ) {
+			// Portrait
+			$crop_x    = 0;
+			$crop_y    = absint( ( $height - $width ) / 2 );
+			$crop_size = $width;
+		} elseif ( $width > $height ) {
+			// Landscape
+			$crop_x    = absint( ( $width - $height ) / 2 );
+			$crop_y    = 0;
+			$crop_size = $height;
+		} else {
+			// Square
+			$crop_x    = 0;
+			$crop_y    = 0;
+			$crop_size = $width;
+		}
+
+		return compact( 'crop_x', 'crop_y', 'crop_size' );
+	}
+
+	/**
+	 * This function is used to pass data to the localize script
+	 * so that we can center the cropper and also set the minimum
+	 * cropper.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param float $ratio
+	 * @param array $cropped_size
+	 * @return array
+	 */
+	public function calculate_default_values_for_javascript_cropper( $ratio, $max_size,  $resized_width, $resized_height, $orginial_width, $original_height ) {
+		$init_x = $init_y = $init_size = 0;
+		$min_crop_size  = ( $max_size / $ratio );
+
+		if ( $resized_width < $resized_height ) {
+			// Portrait
+			$init_y    = ( $max_size - $resized_width ) / 2;
+			$init_size = $resized_height;
+		} elseif ( $resized_width > $resized_height ) {
+			// Landscape
+			$init_x    = ( $max_size - $resized_height ) / 2;
+			$init_size = $resized_height;
+		} else {
+			// Square
+			$init_size = $resized_height;
+		}
+
+		return array(
+			'init_x'    => (int) floor( $init_x ),
+			'init_y'    => (int) floor($init_y ),
+			'init_size' => $init_size,
+			'min_size'  => (int) floor( $min_crop_size ),
+			'width'     => $orginial_width,
+			'height'    => $original_height,
+		);
+	}
+
+	/**
+	 * Converts the coordinates from the downsized image to the original image for accurate cropping.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param int   $crop_x
+	 * @param int   $crop_y
+	 * @param int   $crop_width
+	 * @param int   $crop_height
+	 * @param float $ratio
+	 * @return array
+	 */
+	public function convert_coordinates_from_resized_to_full( $crop_x, $crop_y, $crop_width, $crop_height, $ratio ) {
+		return array(
+			'crop_x'      => floor( $crop_x * $ratio ),
+			'crop_y'      => floor( $crop_y * $ratio ),
+			'crop_width'  => floor( $crop_width * $ratio ),
+			'crop_height' => floor( $crop_height * $ratio ),
+		);
+	}
+
+	/**
+	 * Create an attachment 'object'.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param string $cropped              Cropped image URL.
+	 * @param int    $parent_attachment_id Attachment ID of parent image.
+	 * @return array Attachment object.
+	 */
+	public function create_attachment_object( $cropped, $parent_attachment_id ) {
+		$parent     = get_post( $parent_attachment_id );
+		$parent_url = $parent->guid;
+		$url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
+
+		$size       = @getimagesize( $cropped );
+		$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
+
+		$object = array(
+			'ID'             => $parent_attachment_id,
+			'post_title'     => basename( $cropped ),
+			'post_content'   => $url,
+			'post_mime_type' => $image_type,
+			'guid'           => $url,
+			'context'        => 'site-icon'
+		);
+
+		return $object;
+	}
+
+	/**
+	 * Insert an attachment and its metadata.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param array  $object  Attachment object.
+	 * @param string $cropped Cropped image URL.
+	 * @return int Attachment ID.
+	 */
+	public function insert_attachment( $object, $cropped ) {
+		$attachment_id = wp_insert_attachment( $object, $cropped );
+		$metadata      = wp_generate_attachment_metadata( $attachment_id, $cropped );
+
+		/**
+		 * Filter the site icon attachment metadata.
+		 *
+		 * @since 4.3.0
+		 *
+		 * @see wp_generate_attachment_metadata()
+		 *
+		 * @param array $metadata Attachment metadata.
+		 */
+		$metadata = apply_filters( 'site_icon_attachment_metadata', $metadata );
+		wp_update_attachment_metadata( $attachment_id, $metadata );
+
+		return $attachment_id;
+	}
+
+	/**
+	 * Deletes all additional image sizes, used for site icons.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return bool
+	 */
+	public function delete_site_icon() {
+		// We add the filter to make sure that we also delete all the added images.
+		add_filter( 'intermediate_image_sizes', array( WP_Site_Icon::get_instance(), 'intermediate_image_sizes' ) );
+		wp_delete_attachment( get_option( 'site_icon' ), true );
+		remove_filter( 'intermediate_image_sizes', array( WP_Site_Icon::get_instance(), 'intermediate_image_sizes' ) );
+
+		return delete_option( 'site_icon' );
+	}
+
+	/**
+	 * Deletes the Site Icon when the image file is deleted.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param int $post_id Attachment ID.
+	 */
+	public function delete_attachment_data( $post_id ) {
+		$site_icon_id = get_option( 'site_icon' );
+
+		if ( $site_icon_id && $post_id == $site_icon_id ) {
+			delete_option( 'site_icon' );
+		}
+	}
+
+	/**
+	 * Adds custom image sizes when meta data for an image is requested, that happens to be used as Site Icon.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @param null|array|string $value    The value get_metadata() should
+	 *                                    return - a single metadata value,
+	 *                                    or an array of values.
+	 * @param int               $post_id  Post ID.
+	 * @param string            $meta_key Meta key.
+	 * @param string|array      $single   Meta value, or an array of values.
+	 * @return array|null|string
+	 */
+	public function get_post_metadata( $value, $post_id, $meta_key, $single ) {
+		$site_icon_id = get_option( 'site_icon' );
+
+		if ( $post_id == $site_icon_id && '_wp_attachment_backup_sizes' == $meta_key && $single ) {
+			add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
+		}
+
+		return $value;
+	}
+
+}
+
+
+
+

Property changes on: wp-admin/includes/class-wp-site-icon-admin-processing.php
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: wp-admin/includes/class-wp-site-icon-admin-ui.php
===================================================================
--- wp-admin/includes/class-wp-site-icon-admin-ui.php	(revision 0)
+++ wp-admin/includes/class-wp-site-icon-admin-ui.php	(working copy)
@@ -0,0 +1,308 @@
+<?php
+
+class WP_Site_Icon_Admin_UI {
+	/**
+	 * The size to which to crop the image so that we can display it in the UI nicely.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @var int
+	 *
+	 * TO DO: Rename
+	 */
+	public $page_crop = 512;
+
+	var $admin_ui_processing;
+	var $site_icon;
+	var $admin_page_hook;
+
+	public function __construct( $admin_ui_processing, $site_icon ) {
+		$this->admin_ui_processing = $admin_ui_processing;
+		$this->site_icon = $site_icon;
+
+		// Add the favicon to the backend.
+		add_action( 'admin_head', 'wp_site_icon' );
+
+		add_action( 'admin_menu', array( $this, 'add_site_icon_page_to_menu' ) );
+		add_action( 'admin_init', array( $this, 'add_upload_page_settings' ) );
+
+		add_action( 'admin_action_set_site_icon',    array( $this, 'set_site_icon'    ) );
+		add_action( 'admin_action_remove_site_icon', array( $this, 'remove_site_icon' ) );
+	}
+
+	// To Do: nonce checking
+	public function site_icon_page_controller() {
+		$action = isset( $_GET['action'] ) ? $_GET['action'] : 'select-site-icon';
+
+		switch ( $action ) {
+			case 'select-site-icon':
+				$this->display_upload_page();
+				break;
+
+			case 'crop-site-icon':
+				// Handle image upload for the no Javascript version.
+				if ( isset ( $_GET['upload'] ) ) {
+					$attachment_id = $this->admin_ui_processing->upload_site_icon_image();
+				} else {
+					// The Javascript upload skips the select and upload steps, providing the attachment ID.
+					$attachment_id = $_GET['file'];
+				}
+
+				// Verify that the image is large enough.
+				$image_size = $this->admin_ui_processing->get_image_size_from_attachment( $attachment_id );
+
+				// TO DO: Move this to a method.
+				if ( $image_size[0] < $this->site_icon->min_size ) {
+					add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in width.' ), $this->site_icon->min_size ) );
+					$this->display_upload_page();
+				} elseif ( $image_size[1] < $this->site_icon->min_size ) {
+					add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in height.' ), $this->site_icon->min_size ) );
+					$this->display_upload_page();
+				} else {
+					// TO DO: Move this to a method.
+					// URL of the uploaded image.
+					$image_url = $this->admin_ui_processing->get_site_icon_image_url( $attachment_id );
+					// Dimensions of the uploaded image adapted to the admin.
+					$max_height = $this->admin_ui_processing->calculate_height_of_image_for_cropping( $attachment_id, $this->page_crop );
+					// Add the default crop values for the no JS version.
+					$default_crop = $this->admin_ui_processing->calculate_default_values_for_crop( $this->page_crop, $max_height );
+					// Ratio for cropping
+					$crop_ratio = $image_size[0] / $this->page_crop;
+
+					$this->display_crop_page( $attachment_id, $image_url, $this->page_crop, $max_height, $default_crop, $crop_ratio );
+				}
+				break;
+
+			default:
+				wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) );
+				exit;
+		}
+	}
+
+	/**
+	 * Adds the Site Icon Page to the admin menu.
+	 *
+	 * The `parent_slug` argument in `add_menu_page()` is set to `null`, so that no link is added in the admin interface.
+	 *
+	 * @since 4.3.0
+	 */
+	public function add_site_icon_page_to_menu() {
+		$hook = add_submenu_page( null, __( 'Site Icon' ), __( 'Site Icon' ), 'manage_options', 'site-icon', array( $this, 'site_icon_page_controller' ) );
+
+		add_action( "admin_print_scripts-$hook", array( $this, 'enqueue_scripts' ) );
+	}
+
+	/**
+	 * Register a settings section for uploading a Site Icon image.
+	 *
+	 * @since 4.3.0
+	 */
+	public function add_upload_page_settings() {
+		add_settings_section( 'site-icon-upload', false, false, 'site-icon-upload' );
+		add_settings_field( 'site-icon-upload', __( 'Upload Image' ), array( $this, 'display_upload_page_image_selection' ), 'site-icon-upload', 'site-icon-upload', array(
+			'label_for' => 'site-icon-upload',
+		) );
+	}
+
+	/**
+	 * Add scripts to admin settings pages.
+	 *
+	 * @since 4.3.0
+	 */
+	public function enqueue_scripts() {
+		wp_enqueue_style( 'jcrop' );
+		wp_enqueue_script( 'site-icon-crop' );
+	}
+
+	/**
+	 * Display the admin page for uploading a Site Icon image.
+	 *
+	 * This screen is only visible when Javascript is deactivated.
+	 *
+	 * @since 4.3.0
+	 */
+	public function display_upload_page() {
+		?>
+		<div class="wrap">
+			<h2><?php _e( 'Add Site Icon' ); ?></h2>
+			<?php settings_errors( 'site-icon' ); ?>
+			<?php do_settings_sections( 'site-icon-upload' ); ?>
+		</div>
+	<?php
+	}
+
+	/**
+	 * Settings field for file upload.
+	 *
+	 * @since 4.3.0
+	 */
+	public function display_upload_page_image_selection() {
+		// Render modal for uploading via Javascript.
+		// TO DO: Script enqueuing should be done in a single method.
+		wp_enqueue_media();
+		wp_enqueue_script( 'site-icon' );
+		wp_dequeue_script( 'site-icon-crop' );
+
+		$update_url = esc_url( add_query_arg( array(
+			'page' => 'site-icon',
+			'action' => 'crop-site-icon',
+		), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) );
+		?>
+		<p class="hide-if-no-js">
+			<label class="screen-reader-text" for="choose-from-library-link"><?php _e( 'Choose an image from your media library:' ); ?></label>
+			<?php
+				printf( '<button type="button" id="choose-from-library-link" class="button" data-update-link="%$1s" data-choose="%$2s" data-update="%$3s">%$4s</button>',
+					esc_attr( $update_url ),
+					esc_attr__( 'Choose a Site Icon' ),
+					esc_attr__( 'Set as Site Icon' ),
+					__( 'Choose Image' )
+				);
+			?>
+		</p>
+
+		<?php // Upload form for when Javascript is deactivated ?>
+		<form class="hide-if-js" action="<?php echo esc_url( admin_url( 'options-general.php?page=site-icon&action=crop-site-icon&upload' ) ); ?>" method="post" enctype="multipart/form-data">
+			<input name="action" value="crop_site_icon" type="hidden" />
+			<input name="site-icon" type="file" />
+			<input name="submit" value="<?php esc_attr_e( 'Upload Image' ); ?>" type="submit" class="button button-primary" />
+			<p class="description">
+				<?php printf( __( 'The image is recommended to be a square image of at least %spx in both width and height.' ), "<strong>" . absint( $this->site_icon->min_size ) . '</strong>' ); ?>
+			</p>
+			<?php wp_nonce_field( 'crop-site-icon' ); ?>
+		</form>
+	<?php
+	}
+
+	public function display_crop_page( $attachment_id, $image_url, $resized_image_width, $resized_image_height, $default_crop, $crop_ratio ) {
+		check_admin_referer( 'crop-site-icon' );
+
+		// TO DO: Script enqueuing should be done in a single method.
+		$image_size = $this->admin_ui_processing->get_attachment_image_size( $attachment_id );
+		wp_localize_script( 'site-icon-crop', 'wpSiteIconCropData', $this->admin_ui_processing->calculate_default_values_for_javascript_cropper( $crop_ratio, $this->page_crop, $resized_image_width, $resized_image_height, $image_size[0], $image_size[1] ) );
+	?>
+		<div class="wrap">
+			<h2 class="site-icon-title"><?php _e( 'Site Icon' ); ?></h2>
+			<?php settings_errors( 'site-icon' ); ?>
+
+			<div class="site-icon-crop-shell">
+				<form action="options-general.php" method="post" enctype="multipart/form-data">
+					<p class="hide-if-no-js description"><?php _e('Choose the part of the image you want to use as your site icon.'); ?></p>
+					<p class="hide-if-js description"><strong><?php _e( 'You need Javascript to choose a part of the image.'); ?></strong></p>
+					<?php
+						// Image which is used to select the right cropping.
+						// This image needs to be resized to allow for easy cropping.
+						printf( '<img src="%1$s" id="crop-image" class="site-icon-crop-image" width="%2$s" height="%3$s" alt="%4$s" />',
+							esc_url( $image_url ),
+							absint( $resized_image_width ),
+							absint( $resized_image_height ),
+							esc_attr__( 'Image to be cropped' )
+						);
+
+						// Site icon preview in browser bar and on mobile.
+					?>
+					<div class="site-icon-crop-preview-shell hide-if-no-js">
+						<h3><?php _e( 'Preview' ); ?></h3>
+						<strong><?php _e( 'As your favicon' ); ?></strong>
+						<div class="site-icon-crop-favicon-preview-shell">
+							<img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt="<?php esc_attr_e( 'Browser Chrome' ); ?>"/>
+							<div class="site-icon-crop-preview-favicon">
+								<img src="<?php echo esc_url( $image_url ); ?>" id="preview-favicon" alt="<?php esc_attr_e( 'Preview Favicon' ); ?>"/>
+							</div>
+							<span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span>
+						</div>
+						<strong><?php _e( 'As a mobile icon' ); ?></strong>
+						<div class="site-icon-crop-preview-homeicon">
+							<img src="<?php echo esc_url( $image_url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/>
+						</div>
+					</div>
+
+					<?php // Default crop values for no JS fallback. ?>
+					<input type="hidden" id="crop-x" name="crop-x" value="<?php echo absint( $default_crop['crop_x'] ); ?>" />
+					<input type="hidden" id="crop-y" name="crop-y" value="<?php echo absint( $default_crop['crop_y'] ); ?>" />
+					<input type="hidden" id="crop-width" name="crop-w" value="<?php echo absint( $default_crop['crop_size'] ); ?>" />
+					<input type="hidden" id="crop-height" name="crop-h" value="<?php echo absint( $default_crop['crop_size'] ); ?>" />
+
+					<input type="hidden" name="action" value="set_site_icon" />
+					<input type="hidden" name="attachment_id" value="<?php echo esc_attr( $attachment_id ); ?>" />
+
+					<input type="hidden" name="crop_ratio" value="<?php echo esc_attr( $crop_ratio ); ?>" />
+					<?php if ( empty( $_POST ) && isset( $_GET['file'] ) ) : ?>
+						<input type="hidden" name="create-new-attachment" value="true" />
+					<?php endif; ?>
+					<?php wp_nonce_field( 'set-site-icon' ); ?>
+
+					<p class="submit">
+						<?php submit_button( __( 'Crop and Publish' ), 'primary hide-if-no-js', 'submit', false ); ?>
+						<?php submit_button( __( 'Publish' ), 'primary hide-if-js', 'submit', false ); ?>
+						<a class="button secondary" href="options-general.php"><?php _e( 'Cancel' ); ?></a>
+					</p>
+				</form>
+			</div>
+		</div>
+	<?php
+	}
+
+	/**
+	 * Saves a new Site Icon.
+	 *
+	 * TO DO: Split this apart, and move code to smaller methods in `WP_Site_Icon_Admin_Processing`.
+	 *
+	 * @since 4.3.0
+	 */
+	public function set_site_icon() {
+		check_admin_referer( 'set-site-icon' );
+
+		// Delete any existing site icon images.
+		$this->admin_ui_processing->delete_site_icon();
+
+		$attachment_id = absint( $_POST['attachment_id'] );
+
+		// TODO
+		if ( empty( $_POST['skip-cropping'] ) ) {
+			$crop_ratio = (float) $_POST['crop_ratio'];
+			$crop_data = $this->admin_ui_processing->convert_coordinates_from_resized_to_full( $_POST['crop-x'], $_POST['crop-y'], $_POST['crop-w'], $_POST['crop-h'], $crop_ratio );
+			$cropped = wp_crop_image( $attachment_id, $crop_data['crop_x'], $crop_data['crop_y'], $crop_data['crop_width'], $crop_data['crop_height'], $this->site_icon->min_size, $this->site_icon->min_size );
+		} 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' ) );
+		}
+
+		$object = $this->admin_ui_processing->create_attachment_object( $cropped, $attachment_id );
+
+		if ( ! empty( $_POST['create-new-attachment'] ) ) {
+			unset( $object['ID'] );
+		}
+
+		// Update the attachment
+		add_filter( 'intermediate_image_sizes_advanced', array( $this->site_icon, 'additional_sizes' ) );
+		$attachment_id = $this->admin_ui_processing->insert_attachment( $object, $cropped );
+		remove_filter( 'intermediate_image_sizes_advanced', array( $this->site_icon, 'additional_sizes' ) );
+
+		// Save the site_icon data into option
+		update_option( 'site_icon', $attachment_id );
+
+		add_settings_error( 'site-icon', 'icon-updated', __( 'Site Icon updated.' ), 'updated' );
+	}
+
+	/**
+	 * Removes site icon.
+	 *
+	 * @since 4.3.0
+	 */
+	public function remove_site_icon() {
+		check_admin_referer( 'remove-site-icon' );
+
+		// TO DO: Check return value to display success message.
+		$this->admin_ui_processing->delete_site_icon();
+
+		add_settings_error( 'site-icon', 'icon-removed', __( 'Site Icon removed.' ), 'updated' );
+	}
+
+}
+
+$site_icon_admin = new WP_Site_Icon_Admin_UI( new WP_Site_Icon_Admin_Processing(), WP_Site_Icon::get_instance() );
\ No newline at end of file

Property changes on: wp-admin/includes/class-wp-site-icon-admin-ui.php
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: wp-admin/includes/class-wp-site-icon.php
===================================================================
--- wp-admin/includes/class-wp-site-icon.php	(revision 33173)
+++ wp-admin/includes/class-wp-site-icon.php	(working copy)
@@ -1,11 +1,7 @@
 <?php
 
-/**
- * Class WP_Site_Icon.
- *
- * @since 4.3.0
- */
 class WP_Site_Icon {
+	private static $instance = null;
 
 	/**
 	 * The minimum size of the site icon.
@@ -17,18 +13,9 @@
 	public $min_size  = 512;
 
 	/**
-	 * The size to which to crop the image so that we can display it in the UI nicely.
 	 *
 	 * @since 4.3.0
 	 *
-	 * @var int
-	 */
-	public $page_crop = 512;
-
-	/**
-	 *
-	 * @since 4.3.0
-	 *
 	 * @var array
 	 */
 	public $site_icon_sizes = array(
@@ -50,436 +37,32 @@
 		32,
 	);
 
-	/**
-	 * Register our actions and filters.
-	 *
-	 * @since 4.3.0
-	 */
-	public function __construct() {
-
-		// Add the favicon to the backend.
-		add_action( 'admin_menu', array( $this, 'admin_menu_upload_site_icon' ) );
-
-		add_action( 'admin_action_set_site_icon',    array( $this, 'set_site_icon'    ) );
-		add_action( 'admin_action_remove_site_icon', array( $this, 'remove_site_icon' ) );
-
-		add_action( 'delete_attachment', array( $this, 'delete_attachment_data' ), 10, 1 );
-		add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 );
-	}
-
-	/**
-	 * Add a hidden upload page.
-	 *
-	 * There is no need to access it directly.
-	 *
-	 * @since 4.3.0
-	 */
-	public function admin_menu_upload_site_icon() {
-		$hook = add_submenu_page( null, __( 'Site Icon' ), __( 'Site Icon' ), 'manage_options', 'site-icon', array( $this, 'upload_site_icon_page' ) );
-
-		add_action( "load-$hook", array( $this, 'add_upload_settings' ) );
-		add_action( "load-$hook", array( $this, 'maybe_skip_cropping' ) );
-		add_action( "admin_print_scripts-$hook", array( $this, 'enqueue_scripts' ) );
-	}
-
-	/**
-	 * Add scripts to admin settings pages.
-	 *
-	 * @since 4.3.0
-	 */
-	public function enqueue_scripts() {
-		wp_enqueue_style( 'jcrop' );
-		wp_enqueue_script( 'site-icon-crop' );
-	}
-
-	/**
-	 * Load on when the admin is initialized.
-	 *
-	 * @since 4.3.0
-	 */
-	public function add_upload_settings() {
-		add_settings_section( 'site-icon-upload', false, false, 'site-icon-upload' );
-		add_settings_field( 'site-icon-upload', __( 'Upload Image' ), array( $this, 'upload_field' ), 'site-icon-upload', 'site-icon-upload', array(
-			'label_for' => 'site-icon-upload',
-		) );
-	}
-
-	/**
-	 * Removes site icon.
-	 *
-	 * @since 4.3.0
-	 */
-	public function remove_site_icon() {
-		check_admin_referer( 'remove-site-icon' );
-
-		$this->delete_site_icon();
-
-		add_settings_error( 'site-icon', 'icon-removed', __( 'Site Icon removed.' ), 'updated' );
-	}
-
-	/**
-	 * Uploading a site_icon is a 3 step process
-	 *
-	 * 1. Select the file to upload
-	 * 2. Crop the file
-	 * 3. Confirmation
-	 *
-	 * @since 4.3.0
-	 */
-	public function upload_site_icon_page() {
-		$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'select_site_icon';
-
-		switch ( $action ) {
-			case 'select_site_icon':
-				$this->select_page();
-				break;
-
-			case 'crop_site_icon':
-				$this->crop_page();
-				break;
-
-			default:
-				wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) );
-				exit;
+	static function get_instance() {
+		if ( is_null( self::$instance ) ) {
+			self::$instance = new WP_Site_Icon;
 		}
+		return self::$instance;
 	}
 
 	/**
-	 * Displays the site_icon form to upload the image.
+	 * Add Site Icon sizes to the array of image sizes on demand.
 	 *
 	 * @since 4.3.0
-	 */
-	public function select_page() {
-		?>
-		<div class="wrap">
-			<h1><?php _e( 'Add Site Icon' ); ?></h1>
-			<?php settings_errors( 'site-icon' ); ?>
-			<?php do_settings_sections( 'site-icon-upload' ); ?>
-		</div>
-	<?php
-	}
-
-	/**
-	 * Settings field for file upload.
 	 *
-	 * @since 4.3.0
+	 * @param array $sizes
+	 * @return array
 	 */
-	public function upload_field() {
-		wp_enqueue_media();
-		wp_enqueue_script( 'site-icon' );
-		wp_dequeue_script( 'site-icon-crop' );
-
-		$update_url = esc_url( add_query_arg( array(
-			'page' => 'site-icon',
-			'action' => 'crop_site_icon',
-		), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) );
-		?>
-		<p class="hide-if-no-js">
-			<label class="screen-reader-text" for="choose-from-library-link"><?php _e( 'Choose an image from your media library:' ); ?></label>
-			<button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( $this->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Choose Image' ); ?></button>
-		</p>
-		<form class="hide-if-js" action="<?php echo esc_url( admin_url( 'options-general.php?page=site-icon' ) ); ?>" method="post" enctype="multipart/form-data">
-			<input name="action" value="crop_site_icon" type="hidden" />
-			<input name="site-icon" type="file" />
-			<input name="submit" value="<?php esc_attr_e( 'Upload Image' ); ?>" type="submit" class="button button-primary" />
-			<p class="description">
-				<?php printf( __( 'The image is recommended to be a square image of at least %spx in both width and height.' ), "<strong>$this->min_size</strong>" ); ?>
-			</p>
-			<?php wp_nonce_field( 'crop-site-icon' ); ?>
-		</form>
-	<?php
-	}
-
-	/**
-	 * Check if the image needs cropping.
-	 *
-	 * If it doesn't need cropping, proceed to set the icon.
-	 *
-	 * @since 4.3.0
-	 */
-	public function maybe_skip_cropping() {
-		if ( empty( $_REQUEST['action'] ) || 'crop_site_icon' !== $_REQUEST['action'] ) {
-			return;
+	public function intermediate_image_sizes( $sizes = array() ) {
+		/** This filter is documented in wp-admin/includes/site-icon.php */
+		$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
+		foreach ( $this->site_icon_sizes as $size ) {
+			$sizes[] = 'site_icon-' . $size;
 		}
 
-		check_admin_referer( 'crop-site-icon' );
-
-		list( $attachment_id, $url, $image_size ) = $this->get_upload_data();
-
-		if ( $image_size[0] == $image_size[1] && $image_size[0] == $this->min_size ) {
-			// No cropping required.
-
-			$url = add_query_arg( array(
-				'attachment_id'         => $attachment_id,
-				'skip-cropping'         => true,
-				'create-new-attachment' => true,
-				'action'                => 'set_site_icon',
-			), wp_nonce_url( admin_url( 'options-general.php' ), 'set-site-icon' ) );
-
-			wp_safe_redirect( $url );
-			die();
-		}
+		return $sizes;
 	}
 
 	/**
-	 * Crop a the image admin view.
-	 *
-	 * @since 4.3.0
-	 */
-	public function crop_page() {
-		check_admin_referer( 'crop-site-icon' );
-
-		list( $attachment_id, $url, $image_size ) = $this->get_upload_data();
-
-		if ( $image_size[0] < $this->min_size ) {
-			add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in width.' ), $this->min_size ) );
-
-			// back to step one
-			$this->select_page();
-
-			return;
-		}
-
-		if ( $image_size[1] < $this->min_size ) {
-			add_settings_error( 'site-icon', 'too-small', sprintf( __( 'The selected image is smaller than %upx in height.' ), $this->min_size ) );
-
-			// Back to step one.
-			$this->select_page();
-
-			return;
-		}
-
-		wp_localize_script( 'site-icon-crop', 'wpSiteIconCropData', array(
-			'init_x'    => 0,
-			'init_y'    => 0,
-			'init_size' => $this->min_size,
-			'min_size'  => $this->min_size,
-			'width'     => $image_size[0],
-			'height'    => $image_size[1],
-		) );
-		?>
-
-		<div class="wrap">
-			<h1 class="site-icon-title"><?php _e( 'Site Icon' ); ?></h1>
-			<?php settings_errors( 'site-icon' ); ?>
-
-			<div class="site-icon-crop-shell">
-				<form action="options-general.php" method="post" enctype="multipart/form-data">
-					<p class="hide-if-no-js description"><?php _e('Choose the part of the image you want to use as your site icon.'); ?></p>
-					<p class="hide-if-js description"><strong><?php _e( 'You need Javascript to choose a part of the image.'); ?></strong></p>
-
-					<div class="site-icon-crop-wrapper">
-						<img src="<?php echo esc_url( $url ); ?>" id="crop-image" class="site-icon-crop-image" width="512" height="" alt="<?php esc_attr_e( 'Image to be cropped' ); ?>"/>
-					</div>
-
-					<div class="site-icon-crop-preview-shell hide-if-no-js">
-						<h3><?php _e( 'Preview' ); ?></h3>
-						<strong><?php _e( 'As a browser icon' ); ?></strong>
-						<div class="site-icon-crop-favicon-preview-shell">
-							<img src="images/browser.png" class="site-icon-browser-preview" width="182" height="" alt="<?php esc_attr_e( 'Browser Chrome' ); ?>"/>
-
-							<div class="site-icon-crop-preview-favicon">
-								<img src="<?php echo esc_url( $url ); ?>" id="preview-favicon" alt="<?php esc_attr_e( 'Preview Favicon' ); ?>"/>
-							</div>
-							<span class="site-icon-browser-title"><?php bloginfo( 'name' ); ?></span>
-						</div>
-
-						<strong><?php _e( 'As an app icon' ); ?></strong>
-						<div class="site-icon-crop-preview-homeicon">
-							<img src="<?php echo esc_url( $url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/>
-						</div>
-					</div>
-
-					<input type="hidden" id="crop-x" name="crop-x" value="0" />
-					<input type="hidden" id="crop-y" name="crop-y" value="0" />
-					<input type="hidden" id="crop-width" name="crop-w" value="<?php echo esc_attr( $this->min_size ); ?>" />
-					<input type="hidden" id="crop-height" name="crop-h" value="<?php echo esc_attr( $this->min_size ); ?>" />
-
-					<input type="hidden" name="action" value="set_site_icon" />
-					<input type="hidden" name="attachment_id" value="<?php echo esc_attr( $attachment_id ); ?>" />
-					<?php if ( empty( $_POST ) && isset( $_GET['file'] ) ) : ?>
-						<input type="hidden" name="create-new-attachment" value="true" />
-					<?php endif; ?>
-					<?php wp_nonce_field( 'set-site-icon' ); ?>
-
-					<p class="submit">
-						<?php submit_button( __( 'Crop and Publish' ), 'primary hide-if-no-js', 'submit', false ); ?>
-						<?php submit_button( __( 'Publish' ), 'primary hide-if-js', 'submit', false ); ?>
-						<a class="button secondary" href="options-general.php"><?php _e( 'Cancel' ); ?></a>
-					</p>
-				</form>
-			</div>
-		</div>
-	<?php
-	}
-
-	/**
-	 * Saves a new Site Icon.
-	 *
-	 * @since 4.3.0
-	 */
-	public function set_site_icon() {
-		check_admin_referer( 'set-site-icon' );
-
-		$attachment_id          = absint( $_REQUEST['attachment_id'] );
-		$create_new_attachement = ! empty( $_REQUEST['create-new-attachment'] );
-
-		/*
-		 * If the current attachment as been set as site icon don't delete it.
-		 */
-		if ( get_option( 'site_icon' ) == $attachment_id ) {
-			// Get the file path.
-			$image_url = get_attached_file( $attachment_id );
-
-			// Update meta data and possibly regenerate intermediate sizes.
-			add_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) );
-			$this->update_attachment_metadata( $attachment_id, $image_url );
-			remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) );
-
-		} else {
-			// Delete any existing site icon images.
-			$this->delete_site_icon();
-
-			if ( empty( $_REQUEST['skip-cropping'] ) ) {
-				$cropped = wp_crop_image( $attachment_id, $_REQUEST['crop-x'], $_REQUEST['crop-y'], $_REQUEST['crop-w'], $_REQUEST['crop-h'], $this->min_size, $this->min_size );
-
-			} elseif ( $create_new_attachement ) {
-				$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' ) );
-			}
-
-			$object = $this->create_attachment_object( $cropped, $attachment_id );
-
-			if ( $create_new_attachement ) {
-				unset( $object['ID'] );
-			}
-
-			// Update the attachment.
-			add_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) );
-			$attachment_id = $this->insert_attachment( $object, $cropped );
-			remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'additional_sizes' ) );
-
-			// Save the site_icon data into option
-			update_option( 'site_icon', $attachment_id );
-		}
-
-		add_settings_error( 'site-icon', 'icon-updated', __( 'Site Icon updated.' ), 'updated' );
-	}
-
-	/**
-	 * Upload the file to be cropped in the second step.
-	 *
-	 * @since 4.3.0
-	 */
-	public function handle_upload() {
-		$uploaded_file = $_FILES['site-icon'];
-		$file_type     = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'] );
-		if ( ! wp_match_mime_types( 'image', $file_type['type'] ) ) {
-			wp_die( __( 'The uploaded file is not a valid image. Please try again.' ) );
-		}
-
-		$file = wp_handle_upload( $uploaded_file, array( 'test_form' => false ) );
-
-		if ( isset( $file['error'] ) ) {
-			wp_die( $file['error'], __( 'Image Upload Error' ) );
-		}
-
-		$url      = $file['url'];
-		$type     = $file['type'];
-		$file     = $file['file'];
-		$filename = basename( $file );
-
-		// Construct the object array
-		$object = array(
-			'post_title'     => $filename,
-			'post_content'   => $url,
-			'post_mime_type' => $type,
-			'guid'           => $url,
-			'context'        => 'site-icon',
-		);
-
-		// Save the data
-		$attachment_id = wp_insert_attachment( $object, $file );
-
-		return compact( 'attachment_id', 'file', 'filename', 'url', 'type' );
-	}
-
-	/**
-	 * Create an attachment 'object'.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param string $cropped              Cropped image URL.
-	 * @param int    $parent_attachment_id Attachment ID of parent image.
-	 * @return array Attachment object.
-	 */
-	public function create_attachment_object( $cropped, $parent_attachment_id ) {
-		$parent     = get_post( $parent_attachment_id );
-		$parent_url = $parent->guid;
-		$url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
-
-		$size       = @getimagesize( $cropped );
-		$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
-
-		$object = array(
-			'ID'             => $parent_attachment_id,
-			'post_title'     => basename( $cropped ),
-			'post_content'   => $url,
-			'post_mime_type' => $image_type,
-			'guid'           => $url,
-			'context'        => 'site-icon'
-		);
-
-		return $object;
-	}
-
-	/**
-	 * Insert an attachment.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param array  $object Attachment object.
-	 * @param string $file   File path of the attached image.
-	 * @return int           Attachment ID
-	 */
-	public function insert_attachment( $object, $file ) {
-		$attachment_id = wp_insert_attachment( $object, $file );
-		$this->update_attachment_metadata( $attachment_id, $file );
-
-		return $attachment_id;
-	}
-
-	/**
-	 * Update the metadata of an attachment.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param int    $attachment_id Attachment ID
-	 * @param string $file          File path of the attached image.
-	 */
-	public function update_attachment_metadata( $attachment_id, $file ) {
-		$metadata = wp_generate_attachment_metadata( $attachment_id, $file );
-
-		/**
-		 * Filter the site icon attachment metadata.
-		 *
-		 * @since 4.3.0
-		 *
-		 * @see wp_generate_attachment_metadata()
-		 *
-		 * @param array $metadata Attachment metadata.
-		 */
-		$metadata = apply_filters( 'site_icon_attachment_metadata', $metadata );
-		wp_update_attachment_metadata( $attachment_id, $metadata );
-	}
-
-	/**
 	 * Add additional sizes to be made when creating the site_icon images.
 	 *
 	 * @since 4.3.0
@@ -505,7 +88,7 @@
 
 		// ensure that we only resize the image into
 		foreach ( $sizes as $name => $size_array ) {
-			if ( isset( $size_array['crop'] ) ) {
+			if ( $size_array['crop'] ) {
 				$only_crop_sizes[ $name ] = $size_array;
 			}
 		}
@@ -523,105 +106,5 @@
 		return $only_crop_sizes;
 	}
 
-	/**
-	 * Add Site Icon sizes to the array of image sizes on demand.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param array $sizes
-	 * @return array
-	 */
-	public function intermediate_image_sizes( $sizes = array() ) {
-		/** This filter is documented in wp-admin/includes/site-icon.php */
-		$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
-		foreach ( $this->site_icon_sizes as $size ) {
-			$sizes[] = 'site_icon-' . $size;
-		}
 
-		return $sizes;
-	}
-
-	/**
-	 * Deletes all additional image sizes, used for site icons.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @return bool
-	 */
-	public function delete_site_icon() {
-		// We add the filter to make sure that we also delete all the added images.
-		add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
-		wp_delete_attachment( get_option( 'site_icon' ), true );
-		remove_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
-
-		return delete_option( 'site_icon' );
-	}
-
-	/**
-	 * Deletes the Site Icon when the image file is deleted.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param int $post_id Attachment ID.
-	 */
-	public function delete_attachment_data( $post_id ) {
-		$site_icon_id = get_option( 'site_icon' );
-
-		if ( $site_icon_id && $post_id == $site_icon_id ) {
-			delete_option( 'site_icon' );
-		}
-	}
-
-	/**
-	 * Adds custom image sizes when meta data for an image is requested, that happens to be used as Site Icon.
-	 *
-	 * @since 4.3.0
-	 *
-	 * @param null|array|string $value    The value get_metadata() should
-	 *                                    return - a single metadata value,
-	 *                                    or an array of values.
-	 * @param int               $post_id  Post ID.
-	 * @param string            $meta_key Meta key.
-	 * @param string|array      $single   Meta value, or an array of values.
-	 * @return array|null|string
-	 */
-	public function get_post_metadata( $value, $post_id, $meta_key, $single ) {
-		$site_icon_id = get_option( 'site_icon' );
-
-		if ( $post_id == $site_icon_id && '_wp_attachment_backup_sizes' == $meta_key && $single ) {
-			add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
-		}
-
-		return $value;
-	}
-
-	/**
-	 * Get the data required to work with the uploaded image
-	 *
-	 * @since 4.3.0
-	 *
-	 * @return array containing the collected data
-	 */
-	private function get_upload_data() {
-		if ( isset( $_GET['file'] ) ) {
-			$attachment_id = absint( $_GET['file'] );
-			$file          = get_attached_file( $attachment_id, true );
-			$url           = wp_get_attachment_image_src( $attachment_id, 'full' );
-			$url           = $url[0];
-		} else {
-			$upload        = $this->handle_upload();
-			$attachment_id = $upload['attachment_id'];
-			$file          = $upload['file'];
-			$url           = $upload['url'];
-		}
-
-		$image_size = getimagesize( $file );
-
-		return array( $attachment_id, $url, $image_size );
-	}
 }
-
-/**
- * @global WP_Site_Icon $wp_site_icon
- */
-$GLOBALS['wp_site_icon'] = new WP_Site_Icon;
Index: wp-admin/options-general.php
===================================================================
--- wp-admin/options-general.php	(revision 33173)
+++ wp-admin/options-general.php	(working copy)
@@ -131,7 +131,7 @@
 	$upload_url = admin_url( 'options-general.php?page=site-icon' );
 	$update_url = esc_url( add_query_arg( array(
 		'page'   => 'site-icon',
-		'action' => 'crop_site_icon',
+		'action' => 'crop-site-icon',
 	), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) );
 
 	wp_enqueue_media();
@@ -146,7 +146,7 @@
 	<img class="avatar avatar-150" src="<?php site_icon_url( null, 150 ); ?>" height="150" width="150" />
 	<p class="hide-if-no-js">
 		<label class="screen-reader-text" for="choose-from-library-link"><?php _e( 'Choose an image from your media library:' ); ?></label>
-		<button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( $GLOBALS['wp_site_icon']->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Update Site Icon' ); ?></button>
+		<button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( WP_Site_Icon::get_instance()->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Update Site Icon' ); ?></button>
 		<a href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
 	</p>
 	<p class="hide-if-js">
@@ -158,7 +158,7 @@
 
 	<p class="hide-if-no-js">
 		<label class="screen-reader-text" for="choose-from-library-link"><?php _e( 'Choose an image from your media library:' ); ?></label>
-		<button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( $GLOBALS['wp_site_icon']->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Choose Image' ); ?></button>
+		<button type="button" id="choose-from-library-link" class="button" data-size="<?php echo absint( WP_Site_Icon::get_instance()->min_size ); ?>" data-update-link="<?php echo esc_attr( $update_url ); ?>" data-choose="<?php esc_attr_e( 'Choose a Site Icon' ); ?>" data-update="<?php esc_attr_e( 'Set as Site Icon' ); ?>"><?php _e( 'Choose Image' ); ?></button>
 	</p>
 	<a class="button hide-if-js" href="<?php echo esc_url( $upload_url ); ?>"><?php _e( 'Add a Site Icon' ); ?></a>
 
