'image/gif',
		'jpeg' => 'image/jpeg',
		'jpg'  => 'image/jpg',
		'png'  => 'image/png',
	);
	/**
	 * Configuration.
	 *
	 * @since 2.2.0
	 * @access private
	 *
	 * @var Config
	 */
	private $config;
	/**
	 * Image Service API class object.
	 *
	 * @since 2.2.0
	 * @access private
	 *
	 * @var Extension_ImageService_API
	 */
	private $api;
	/**
	 * Constructor.
	 *
	 * @since 2.2.0
	 */
	public function __construct() {
		$this->config = Dispatcher::config();
	}
	/**
	 * Get extension information.
	 *
	 * @since 2.2.0
	 * @static
	 *
	 * @global $wp_version WordPress core version.
	 *
	 * @param  array $extensions Extensions.
	 * @param  array $config Configuration.
	 * @return array
	 */
	public static function w3tc_extensions( $extensions, $config ) {
		global $wp_version;
		$description = __(
			'Adds the ability to convert images in the Media Library to the modern WebP format for better performance.',
			'w3-total-cache'
		);
		if ( version_compare( $wp_version, '5.8', '<' ) ) {
			$description .= sprintf(
				// translators: 1: HTML break, 2: WordPress version string, 3: HTML archor open tag, 4: HTML archor close tag.
				__(
					'%1$sThis extension works best in WordPress version 5.8 and higher.  You are running WordPress version %2$s.  Please %3$supdate now%4$s to benefit from this feature.',
					'w3-total-cache'
				),
				'
',
				$wp_version,
				'',
				''
			);
		}
		$settings_url = esc_url( Util_Ui::admin_url( 'upload.php?page=w3tc_extension_page_imageservice&w3tc_imageservice_action=dismiss_activation_notice' ) );
		$library_url  = esc_url( Util_Ui::admin_url( 'upload.php?mode=list' ) );
		$extensions['imageservice'] = array(
			'name'             => 'Image Service',
			'author'           => 'BoldGrid',
			'description'      => esc_html( $description ),
			'author_uri'       => 'https://www.boldgrid.com/',
			'extension_uri'    => 'https://www.boldgrid.com/w3-total-cache/',
			'extension_id'     => 'imageservice',
			'settings_exists'  => false,
			'version'          => '1.0',
			'enabled'          => true,
			'disabled_message' => '',
			'requirements'     => '',
			'path'             => 'w3-total-cache/Extension_ImageService_Plugin.php',
			'notice'           => sprintf(
				// translators: 1: HTML anchor open tag, 2: HTML anchor close tag, 3: HTML anchor open tag, 4: HTML anchor open tag.
				__(
					'Total Cache Image Service has been activated. Now, you can %1$sadjust the settings%2$s or go to the %3$sMedia Library%2$s to convert images to WebP.  %4$sLearn more%2$s.',
					'w3-total-cache'
				),
				'',
				'',
				'',
				''
			),
		);
		// The settings and Media Library links are only valid for single and network sites; not the admin section.
		if ( ! is_network_admin() ) {
			$extensions['imageservice']['extra_links'] = array(
				'' . esc_html__( 'Settings', 'w3-total-cache' ) . '',
				'' . esc_html__( 'Media Library', 'w3-total-cache' ) . '',
			);
		}
		return $extensions;
	}
	/**
	 * Load the admin extension.
	 *
	 * Runs on the "wp_loaded" action.
	 *
	 * @since 2.2.0
	 * @static
	 */
	public static function w3tc_extension_load_admin() {
		$o = new Extension_ImageService_Plugin_Admin();
		// Enqueue scripts.
		add_action( 'admin_enqueue_scripts', array( $o, 'admin_enqueue_scripts' ) );
		/**
		 * Filters the Media list table columns.
		 *
		 * @since 2.5.0
		 *
		 * @param string[] $posts_columns An array of columns displayed in the Media list table.
		 * @param bool     $detached      Whether the list table contains media not attached
		 *                                to any posts. Default true.
		 */
		add_filter( 'manage_media_columns', array( $o, 'add_media_column' ) );
		/**
		 * Fires for each custom column in the Media list table.
		 *
		 * Custom columns are registered using the {@see 'manage_media_columns'} filter.
		 *
		 * @since 2.5.0
		 *
		 * @param string $column_name Name of the custom column.
		 * @param int    $post_id     Attachment ID.
		 */
		add_action( 'manage_media_custom_column', array( $o, 'media_column_row' ), 10, 2 );
		// AJAX hooks.
		add_action( 'wp_ajax_w3tc_imageservice_submit', array( $o, 'ajax_submit' ) );
		add_action( 'wp_ajax_w3tc_imageservice_postmeta', array( $o, 'ajax_get_postmeta' ) );
		add_action( 'wp_ajax_w3tc_imageservice_revert', array( $o, 'ajax_revert' ) );
		add_action( 'wp_ajax_w3tc_imageservice_all', array( $o, 'ajax_convert_all' ) );
		add_action( 'wp_ajax_w3tc_imageservice_revertall', array( $o, 'ajax_revert_all' ) );
		add_action( 'wp_ajax_w3tc_imageservice_counts', array( $o, 'ajax_get_counts' ) );
		add_action( 'wp_ajax_w3tc_imageservice_usage', array( $o, 'ajax_get_usage' ) );
		// Admin notices.
		add_action( 'admin_notices', array( $o, 'display_notices' ) );
		/**
		 * Ensure all network sites include WebP support.
		 *
		 * @link https://make.wordpress.org/core/2021/06/07/wordpress-5-8-adds-webp-support/
		 */
		add_filter(
			'site_option_upload_filetypes',
			function ( $filetypes ) {
				$filetypes = explode( ' ', $filetypes );
				if ( ! in_array( 'webp', $filetypes, true ) ) {
					$filetypes[] = 'webp';
				}
				return implode( ' ', $filetypes );
			}
		);
		// Add bulk actions.
		add_filter( 'bulk_actions-upload', array( $o, 'add_bulk_actions' ) );
		/**
		 * Fires when a custom bulk action should be handled.
		 *
		 * The redirect link should be modified with success or failure feedback
		 * from the action to be used to display feedback to the user.
		 *
		 * The dynamic portion of the hook name, `$screen`, refers to the current screen ID.
		 *
		 * @since 4.7.0
		 *
		 * @link https://core.trac.wordpress.org/browser/tags/5.8/src/wp-admin/upload.php#L206
		 *
		 * @param string $sendback The redirect URL.
		 * @param string $doaction The action being taken.
		 * @param array  $items    The items to take the action on. Accepts an array of IDs of posts,
		 *                         comments, terms, links, plugins, attachments, or users.
		 */
		add_filter( 'handle_bulk_actions-upload', array( $o, 'handle_bulk_actions' ), 10, 3 );
		/**
		 * Handle auto-optimization on upload.
		 *
		 * @link https://core.trac.wordpress.org/browser/tags/5.8/src/wp-includes/post.php#L4401
		 * @link https://developer.wordpress.org/reference/hooks/add_attachment/
		 *
		 * Fires once an attachment has been added.
		 *
		 * @since 2.0.0
		 *
		 * @param int $post_ID Attachment ID.
		 */
		add_action( 'add_attachment', array( $o, 'auto_convert' ) );
		/**
		 * Delete optimizations on parent image delation.
		 *
		 * @link https://core.trac.wordpress.org/browser/tags/5.8/src/wp-includes/post.php#L6134
		 * @link https://developer.wordpress.org/reference/hooks/pre_delete_attachment/
		 *
		 * Filters whether an attachment deletion should take place.
		 *
		 * @since 5.5.0
		 *
		 * @param bool|null $delete       Whether to go forward with deletion.
		 * @param WP_Post   $post         Post object.
		 * @param bool      $force_delete Whether to bypass the Trash.
		 */
		add_filter( 'pre_delete_attachment', array( $o, 'cleanup_optimizations' ), 10, 3 );
		// Add admin menu items.
		add_action( 'admin_menu', array( $o, 'admin_menu' ) );
	}
	/**
	 * Get all images with postmeta key "w3tc_imageservice".
	 *
	 * @since 2.2.0
	 * @static
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_query/
	 *
	 * @return WP_Query
	 */
	public static function get_imageservice_attachments() {
		return new \WP_Query(
			array(
				'post_type'           => 'attachment',
				'post_status'         => 'inherit',
				'post_mime_type'      => self::$mime_types,
				'posts_per_page'      => -1,
				'ignore_sticky_posts' => true,
				'suppress_filters'    => true,
				'meta_key'            => 'w3tc_imageservice', // phpcs:ignore WordPress.DB.SlowDBQuery
			)
		);
	}
	/**
	 * Get all images without postmeta key "w3tc_imageservice".
	 *
	 * @since 2.2.0
	 * @static
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_query/
	 *
	 * @return WP_Query
	 */
	public static function get_eligible_attachments() {
		return new \WP_Query(
			array(
				'post_type'           => 'attachment',
				'post_status'         => 'inherit',
				'post_mime_type'      => self::$mime_types,
				'posts_per_page'      => -1,
				'ignore_sticky_posts' => true,
				'suppress_filters'    => true,
				'meta_key'            => 'w3tc_imageservice', // phpcs:ignore WordPress.DB.SlowDBQuery
				'meta_compare'        => 'NOT EXISTS',
			)
		);
	}
	/**
	 * Get an attachment filesize.
	 *
	 * @since 2.2.0
	 *
	 * @global $wp_filesystem
	 *
	 * @param int $post_id Post id.
	 * @return int
	 */
	public function get_attachment_filesize( $post_id ) {
		WP_Filesystem();
		global $wp_filesystem;
		$size     = 0;
		$filepath = get_attached_file( $post_id );
		if ( $wp_filesystem->exists( $filepath ) ) {
			$size = $wp_filesystem->size( $filepath );
		}
		return $size;
	}
	/**
	 * Get image counts by status.
	 *
	 * @since 2.2.0
	 *
	 * @see self::get_imageservice_attachments()
	 * @see self::get_eligible_attachments()
	 *
	 * @return array
	 */
	public function get_counts() {
		$unconverted_posts  = self::get_eligible_attachments();
		$counts             = array(
			'sending'      => 0,
			'processing'   => 0,
			'converted'    => 0,
			'notconverted' => 0,
			'unconverted'  => $unconverted_posts->post_count,
			'total'        => 0,
		);
		$bytes              = array(
			'sending'      => 0,
			'processing'   => 0,
			'converted'    => 0,
			'notconverted' => 0,
			'unconverted'  => 0,
			'total'        => 0,
		);
		$imageservice_posts = self::get_imageservice_attachments()->posts;
		foreach ( $imageservice_posts as $post ) {
			$imageservice_data = get_post_meta( $post->ID, 'w3tc_imageservice', true );
			$status            = isset( $imageservice_data['status'] ) ? $imageservice_data['status'] : null;
			$filesize_in       = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-in'] ) ?
				$imageservice_data['download']["\0*\0data"]['x-filesize-in'] : 0;
			$filesize_out      = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-out'] ) ?
				$imageservice_data['download']["\0*\0data"]['x-filesize-out'] : 0;
			switch ( $status ) {
				case 'sending':
					$size = $this->get_attachment_filesize( $post->ID );
					$counts['sending']++;
					$bytes['sending'] += $size;
					$bytes['total']   += $size;
					break;
				case 'processing':
					$size = $this->get_attachment_filesize( $post->ID );
					$counts['processing']++;
					$bytes['processing'] += $size;
					$bytes['total']      += $size;
					break;
				case 'converted':
					$counts['converted']++;
					$bytes['converted'] += $filesize_in - $filesize_out;
					$bytes['total']     += $filesize_in - $filesize_out;
					break;
				case 'notconverted':
					$size = $this->get_attachment_filesize( $post->ID );
					$counts['notconverted']++;
					$bytes['notconverted'] += $size;
					$bytes['total']        += $size;
					break;
				case 'unconverted':
					$size = $this->get_attachment_filesize( $post->ID );
					$counts['unconverted']++;
					$bytes['unconverted'] += $size;
					$bytes['total']       += $size;
					break;
				default:
					break;
			}
		}
		foreach ( $unconverted_posts->posts as $post ) {
			$size = $this->get_attachment_filesize( $post->ID );
			if ( $size ) {
				$bytes['unconverted'] += $size;
				$bytes['total']       += $size;
			}
		}
		$counts['total']             = array_sum( $counts );
		$counts['totalbytes']        = $bytes['total'];
		$counts['sendingbytes']      = $bytes['sending'];
		$counts['processingbytes']   = $bytes['processing'];
		$counts['convertedbytes']    = $bytes['converted'];
		$counts['notconvertedbytes'] = $bytes['notconverted'];
		$counts['unconvertedbytes']  = $bytes['unconverted'];
		return $counts;
	}
	/**
	 * Load the extension settings page view.
	 *
	 * @since 2.2.0
	 *
	 * @see Extension_ImageService_Plugin::get_api()
	 * @see Extension_ImageService_Api::get_usage()
	 */
	public function settings_page() {
		$c      = $this->config;
		$counts = $this->get_counts();
		$usage  = get_transient( 'w3tc_imageservice_usage' );
		// Delete transient for displaying activation notice.
		delete_transient( 'w3tc_activation_imageservice' );
		// Save submitted settings.
		$nonce_val                    = Util_Request::get_string( '_wpnonce' );
		$imageservice_compression_val = Util_Request::get_string( 'imageservice___compression' );
		if ( ! empty( $imageservice_compression_val ) && ! empty( $nonce_val ) && wp_verify_nonce( $nonce_val, 'w3tc' ) ) {
			$settings                = $c->get_array( 'imageservice' );
			$settings['compression'] = $imageservice_compression_val;
			$imageservice_auto_val = Util_Request::get_string( 'imageservice___auto' );
			if ( ! empty( $imageservice_auto_val ) ) {
				$settings['auto'] = $imageservice_auto_val;
			}
			$imageservice_visibility_val = Util_Request::get_string( 'imageservice___visibility' );
			if ( ! empty( $imageservice_visibility_val ) ) {
				$settings['visibility'] = $imageservice_visibility_val;
			}
			$c->set( 'imageservice', $settings );
			$c->save();
			// Display notice when saving settings.
			?>
			
			get_usage();
		}
		// Ensure that the monthly limit is represented correctly.
		$usage['limit_monthly'] = $usage['limit_monthly'] ? $usage['limit_monthly'] : __( 'Unlimited', 'w3-total-cache' );
		require W3TC_DIR . '/Extension_ImageService_Page_View.php';
	}
	/**
	 * Add admin menu items.
	 *
	 * @since 2.2.0
	 */
	public function admin_menu() {
		// Add settings submenu to Media top-level menu.
		add_submenu_page(
			'upload.php',
			esc_html__( 'Total Cache Image Service', 'w3-total-cache' ),
			esc_html__( 'Total Cache Image Service', 'w3-total-cache' ),
			'edit_posts',
			'w3tc_extension_page_imageservice',
			array( $this, 'settings_page' )
		);
	}
	/**
	 * Enqueue scripts and styles for admin pages.
	 *
	 * Runs on the "admin_enqueue_scripts" action.
	 *
	 * @since 2.2.0
	 *
	 * @see Util_Ui::admin_url()
	 * @see Licensing_Core::get_tos_choice()
	 */
	public function admin_enqueue_scripts() {
		// Enqueue JavaScript for the Media Library (upload) and extension settings admin pages.
		$page_val         = Util_Request::get_string( 'page' );
		$is_settings_page = ! empty( $page_val ) && 'w3tc_extension_page_imageservice' === $page_val;
		$is_media_page    = 'upload' === get_current_screen()->id;
		if ( $is_settings_page ) {
			wp_enqueue_style( 'w3tc-options' );
		}
		if ( $is_settings_page || $is_media_page ) {
			wp_localize_script( 'w3tc-lightbox', 'w3tc_nonce', array( wp_create_nonce( 'w3tc' ) ) );
			wp_enqueue_script( 'w3tc-lightbox' );
			wp_enqueue_style( 'w3tc-lightbox' );
			wp_register_script(
				'w3tc-imageservice',
				esc_url( plugin_dir_url( __FILE__ ) . 'Extension_ImageService_Plugin_Admin.js' ),
				array( 'jquery' ),
				W3TC_VERSION,
				true
			);
			wp_localize_script(
				'w3tc-imageservice',
				'w3tcData',
				array(
					'nonces'      => array(
						'submit'   => wp_create_nonce( 'w3tc_imageservice_submit' ),
						'postmeta' => wp_create_nonce( 'w3tc_imageservice_postmeta' ),
						'revert'   => wp_create_nonce( 'w3tc_imageservice_revert' ),
					),
					'lang'        => array(
						'convert'          => __( 'Convert', 'w3-total-cache' ),
						'sending'          => __( 'Sending...', 'w3-total-cache' ),
						'submitted'        => __( 'Submitted', 'w3-total-cache' ),
						'processing'       => __( 'Processing...', 'w3-total-cache' ),
						'converted'        => __( 'Converted', 'w3-total-cache' ),
						'notConverted'     => __( 'Not converted', 'w3-total-cache' ),
						'reverting'        => __( 'Reverting...', 'w3-total-cache' ),
						'reverted'         => __( 'Reverted', 'w3-total-cache' ),
						'revert'           => __( 'Revert', 'w3-total-cache' ),
						'error'            => __( 'Error', 'w3-total-cache' ),
						'ajaxFail'         => __( 'Failed to retrieve a response.  Please reload the page to try again.', 'w3-total-cache' ),
						'apiError'         => __( 'API error.  Please reload the page to try again,', 'w3-total-cache' ),
						'refresh'          => __( 'Refresh', 'w3-total-cache' ),
						'refreshing'       => __( 'Refreshing...', 'w3-total-cache' ),
						'settings'         => __( 'Settings', 'w3-total-cache' ),
						'submittedAllDesc' => sprintf(
							// translators: 1: HTML anchor open tag, 2: HTML anchor close tag.
							__( 'Images queued for conversion.  Progress can be seen in the %1$sMedia Library%2$s.', 'w3-total-cache' ),
							'',
							''
						),
						'notConvertedDesc' => sprintf(
							// translators: 1: HTML anchor open tag, 2: HTML anchor close tag.
							__( 'The converted image would be larger than the original; conversion canceled.  %1$sLearn more%2$s.', 'w3-total-cache' ),
							'',
							''
						),
					),
					'tos_choice'  => Licensing_Core::get_tos_choice(),
					'track_usage' => $this->config->get_boolean( 'common.track_usage' ),
					'ga_profile'  => ( defined( 'W3TC_DEVELOPER' ) && W3TC_DEVELOPER ) ? 'UA-2264433-7' : 'UA-2264433-8',
					'settings'    => $this->config->get_array( 'imageservice' ),
					'settingsUrl' => esc_url( Util_Ui::admin_url( 'upload.php?page=w3tc_extension_page_imageservice' ) ),
				)
			);
			wp_enqueue_script( 'w3tc-imageservice' );
			wp_enqueue_style(
				'w3tc-imageservice',
				esc_url( plugin_dir_url( __FILE__ ) . 'Extension_ImageService_Plugin_Admin.css' ),
				array(),
				W3TC_VERSION,
				'all'
			);
		}
	}
	/**
	 * Add image service controls to the Media Library table in list view.
	 *
	 * Runs on the "manage_media_columns" filter.
	 *
	 * @since 2.2.0
	 *
	 * @param string[] $posts_columns An array of columns displayed in the Media list table.
	 * @param bool     $detached      Whether the list table contains media not attached
	 *                                to any posts. Default true.
	 */
	public function add_media_column( $posts_columns, $detached = true ) {
		// Delete transient for displaying activation notice.
		delete_transient( 'w3tc_activation_imageservice' );
		$posts_columns['imageservice'] = ' ' . esc_html__( 'Image Service', 'w3-total-cache' );
		return $posts_columns;
	}
	/**
	 * Fires for each custom column in the Media list table.
	 *
	 * Custom columns are registered using the {@see 'manage_media_columns'} filter.
	 * Runs on the "manage_media_custom_column" action.
	 *
	 * @since 2.5.0
	 *
	 * @see self::remove_optimizations()
	 *
	 * @link https://developer.wordpress.org/reference/functions/size_format/
	 *
	 * @param string $column_name Name of the custom column.
	 * @param int    $post_id     Attachment ID.
	 */
	public function media_column_row( $column_name, $post_id ) {
		static $settings;
		if ( 'imageservice' === $column_name ) {
			$post              = get_post( $post_id );
			$imageservice_data = get_post_meta( $post_id, 'w3tc_imageservice', true );
			$settings = isset( $settings ) ? $settings : $this->config->get_array( 'imageservice' );
			// Display controls and info for eligible images.
			if ( in_array( $post->post_mime_type, self::$mime_types, true ) ) {
				$filepath = get_attached_file( $post_id );
				$status   = isset( $imageservice_data['status'] ) ? $imageservice_data['status'] : null;
				// Check if image still has the converted file.  It could have been deleted.
				if ( 'converted' === $status && isset( $imageservice_data['post_child'] ) ) {
					$child_data = get_post_meta( $imageservice_data['post_child'], 'w3tc_imageservice', true );
					if ( empty( $child_data['is_converted_file'] ) ) {
						$status = null;
						$this->remove_optimizations( $post_id );
					}
				}
				// If processed, then show information.
				if ( 'converted' === $status ) {
					$converted_percent = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-out-percent'] ) ?
						$imageservice_data['download']["\0*\0data"]['x-filesize-out-percent'] : null;
					$reduced_percent   = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-reduced'] ) ?
						$imageservice_data['download']["\0*\0data"]['x-filesize-reduced'] : null;
					$filesize_in       = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-in'] ) ?
						$imageservice_data['download']["\0*\0data"]['x-filesize-in'] : null;
					$filesize_out      = isset( $imageservice_data['download']["\0*\0data"]['x-filesize-out'] ) ?
						$imageservice_data['download']["\0*\0data"]['x-filesize-out'] : null;
					if ( $converted_percent ) {
						$converted_class = rtrim( $converted_percent, '%' ) > 100 ? 'w3tc-converted-increased' : 'w3tc-converted-reduced';
						?>
						
						
						
						
					
					',
						''
					);
					?>
					
					
				
					
				
					
				
				
					 | 
					post_parent );
			}
		}
	}
	/**
	 * Add bulk actions.
	 *
	 * @since 2.2.0
	 *
	 * @param array $actions Bulk actions.
	 * @return array
	 */
	public function add_bulk_actions( array $actions ) {
		$actions['w3tc_imageservice_convert'] = 'W3 Total Convert';
		$actions['w3tc_imageservice_revert']  = 'W3 Total Convert Revert';
		return $actions;
	}
	/**
	 * Handle bulk actions.
	 *
	 * @since 2.2.0
	 *
	 * @see self::submit_images()
	 * @see self::revert_optimizations()
	 *
	 * @link https://developer.wordpress.org/reference/hooks/handle_bulk_actions-screen/
	 * @link https://make.wordpress.org/core/2016/10/04/custom-bulk-actions/
	 * @link https://core.trac.wordpress.org/browser/tags/5.8/src/wp-admin/upload.php#L206
	 *
	 * @since WordPress 4.7.0
	 *
	 * @param string $location The redirect URL.
	 * @param string $doaction The action being taken.
	 * @param array  $post_ids The items to take the action on. Accepts an array of IDs of attachments.
	 * @return string
	 */
	public function handle_bulk_actions( $location, $doaction, array $post_ids ) {
		// Remove custom query args.
		$location = remove_query_arg( array( 'w3tc_imageservice_submitted', 'w3tc_imageservice_reverted' ), $location );
		switch ( $doaction ) {
			case 'w3tc_imageservice_convert':
				$stats = $this->submit_images( $post_ids );
				$location = add_query_arg(
					array(
						'w3tc_imageservice_submitted'  => $stats['submitted'],
						'w3tc_imageservice_successful' => $stats['successful'],
						'w3tc_imageservice_skipped'    => $stats['skipped'],
						'w3tc_imageservice_errored'    => $stats['errored'],
						'w3tc_imageservice_invalid'    => $stats['invalid'],
					),
					$location
				);
				break;
			case 'w3tc_imageservice_revert':
				$this->revert_optimizations( $post_ids );
				$location = add_query_arg( 'w3tc_imageservice_reverted', 1, $location );
				break;
			default:
				break;
		}
		return $location;
	}
	/**
	 * Display bulk action results admin notice.
	 *
	 * @since 2.2.0
	 *
	 * @uses $_GET['w3tc_imageservice_submitted']  Number of submittions.
	 * @uses $_GET['w3tc_imageservice_successful'] Number of successful submissions.
	 * @uses $_GET['w3tc_imageservice_skipped']    Number of skipped submissions.
	 * @uses $_GET['w3tc_imageservice_errored']    Number of errored submissions.
	 * @uses $_GET['w3tc_imageservice_invalid']    Number of invalid submissions.
	 */
	public function display_notices() {
		$submitted = Util_Request::get_integer( 'w3tc_imageservice_submitted' );
		if ( ! empty( $submitted ) ) {
			$successful_val = Util_Request::get_integer( 'w3tc_imageservice_successful' );
			$successful     = ! empty( $successful_val ) ? $successful_val : 0;
			$skipped_val = Util_Request::get_integer( 'w3tc_imageservice_skipped' );
			$skipped     = ! empty( $skipped_val ) ? $skipped_val : 0;
			$errored_val = Util_Request::get_integer( 'w3tc_imageservice_errored' );
			$errored     = ! empty( $errored_val ) ? $errored_val : 0;
			$invalid_val = Util_Request::get_integer( 'w3tc_imageservice_invalid' );
			$invalid     = ! empty( $invalid_val ) ? $invalid_val : 0;
			?>
			
			
				Total Cache Image Service
				
			',
				esc_attr( $submitted )
			);
			// Print extra stats if debug is on.
			if ( defined( 'W3TC_DEBUG' ) && W3TC_DEBUG ) {
				?>
				
				
				
			 
			
			
			Total Cache Image Service
				
			Total Cache Image Service -
				',
							''
						);
				?>