register_hooks();
}
return self::$instance;
}
private function __construct() {
self::$min_size = ( defined( 'SITE_ICON_MIN_SIZE' ) && is_int( SITE_ICON_MIN_SIZE ) ) ? SITE_ICON_MIN_SIZE : self::$min_size;
}
/**
* Register our actions and filters
* @return null
*/
public function register_hooks(){
add_action( 'jetpack_modules_loaded', array( $this, 'jetpack_modules_loaded' ) );
add_action( 'admin_menu', array( $this, 'admin_menu_upload_site_icon' ) );
add_filter( 'display_media_states', array( $this, 'add_media_state' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'admin_init', array( $this, 'delete_site_icon_hook' ) );
add_action( 'admin_print_styles-options-general.php', array( $this, 'add_general_options_styles' ) );
// Add the favicon to the front end and backend if Core's site icon not used.
/**
* As of WP 4.3 and JP 3.6, both are outputting the same icons so no need to fire these.
* This is a temporary solution until Jetpack's module primary function is deprecated.
* In the future, Jetpack's can output other sizes using Core's icon.
*/
if ( ( function_exists( 'has_site_icon' ) && ! has_site_icon() ) || ! function_exists( 'has_site_icon' ) ) {
add_action( 'wp_head', array( $this, 'site_icon_add_meta' ) );
add_action( 'admin_head', array( $this, 'site_icon_add_meta' ) );
add_action( 'atom_head', array( $this, 'atom_icon' ) );
add_action( 'rss2_head', array( $this, 'rss2_icon' ) );
}
// Check if site icon is available in core, and if so convert Jetpack's to use it.
add_action( 'admin_init', array( 'Jetpack', 'jetpack_site_icon_available_in_core' ) );
add_action( 'delete_option', array( 'Jetpack_Site_Icon', 'delete_temp_data' ), 10, 1); // used to clean up after itself.
add_action( 'delete_attachment', array( 'Jetpack_Site_Icon', 'delete_attachment_data' ), 10, 1); // in case user deletes the attachment via
add_filter( 'get_post_metadata', array( 'Jetpack_Site_Icon', 'delete_attachment_images' ), 10, 4 );
}
/**
* After all modules have been loaded.
*/
public function jetpack_modules_loaded() {
Jetpack::enable_module_configurable( $this->module );
Jetpack::module_configuration_load( $this->module, array( $this, 'jetpack_configuration_load' ) );
}
/**
* Add meta elements to a blog header to light up Blavatar icons recognized by user agents.
* @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon
*
*/
public function site_icon_add_meta() {
if (
/**
* Toggles the Favicon meta elements from being loaded.
*
* @module site-icon
*
* @since 3.2.0
*
* @param bool Output Site Icon Meta Elements.
*/
apply_filters( 'site_icon_has_favicon', false )
) {
return;
}
$url_114 = jetpack_site_icon_url( null, 114 );
$url_72 = jetpack_site_icon_url( null, 72 );
$url_32 = jetpack_site_icon_url( null, 32 );
if( $url_32 ) {
echo '' . "\n";
echo '' . "\n";
// windows tiles
echo '' . "\n";
}
}
/**
* Display icons in RSS2.
*/
public function rss2_icon() {
/** This filter is documented in modules/site-icon/jetpack-site-icon.php */
if ( apply_filters( 'site_icon_has_favicon', false ) ) {
return;
}
$rss_title = get_wp_title_rss();
if ( empty( $rss_title ) ) {
$rss_title = get_bloginfo_rss( 'name' );
}
$icon = jetpack_site_icon_url( null, 32 );
if( $icon ) {
echo '
' . convert_chars( $icon ) . '
' . $rss_title . '
' . get_bloginfo_rss( 'url' ) . '
32
32
'."\n";
}
}
/**
* Display icons in atom feeds.
*
*/
public function atom_icon() {
/** This filter is documented in modules/site-icon/jetpack-site-icon.php */
if ( apply_filters( 'site_icon_has_favicon', false ) ) {
return;
}
$url = jetpack_site_icon_url( null, 32 );
if( $url ) {
echo '
' . $url . ' '."\n";
}
}
/**
* Add a hidden upload page from people
*/
public function admin_menu_upload_site_icon() {
$page_hook = add_submenu_page(
null,
__( 'Site Icon Upload', 'jetpack' ),
'',
'manage_options',
'jetpack-site_icon-upload',
array( $this, 'upload_site_icon_page' )
);
add_action( "admin_head-$page_hook", array( $this, 'upload_balavatar_head' ) );
}
/**
* Add styles to the General Settings Screen
*/
public function add_general_options_styles() {
wp_enqueue_style( 'site-icon-admin' );
}
/**
* Add Styles to the Upload UI Page
*
*/
public function upload_balavatar_head() {
wp_register_script( 'jetpack-site-icon-crop', plugin_dir_url( __FILE__ ). "js/site-icon-crop.js" , array( 'jquery', 'jcrop' ) , self::$assets_version, false);
if ( isset( $_REQUEST['step'] ) && $_REQUEST['step'] == 2 ) {
wp_enqueue_script( 'jetpack-site-icon-crop' );
wp_enqueue_style( 'jcrop' );
}
wp_enqueue_style( 'site-icon-admin' );
}
public function add_media_state( $media_states ) {
if ( jetpack_has_site_icon() ) {
global $post;
if( $post->ID == Jetpack_Options::get_option( 'site_icon_id' ) ) {
$media_states[] = __( 'Site Icon', 'jetpack' );
}
}
return $media_states;
}
/**
* Direct the user to the Settings -> General
*/
public static function jetpack_configuration_load() {
wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) );
exit;
}
/**
* Load on when the admin is initialized
*/
public function admin_init() {
/* register the styles and scripts */
wp_register_style( 'site-icon-admin' , plugin_dir_url( __FILE__ ). "css/site-icon-admin.css", array(), self::$assets_version );
// register the settings
add_settings_section(
$this->module,
'',
array( $this, 'site_icon_settings' ),
'general'
);
// We didn't have site_icon_url in 3.2 // this could potentially be removed in a year
if( get_option( 'site_icon_id' ) && ! Jetpack_Options::get_option( 'site_icon_url' ) ) {
Jetpack_Options::update_option( 'site_icon_id', get_option( 'site_icon_id' ) );
Jetpack_Options::update_option( 'site_icon_url', jetpack_site_icon_url( get_current_blog_id(), 512 ) );
delete_option( 'site_icon_id' );
}
}
/**
* Checks for permission to delete the site_icon
*/
public function delete_site_icon_hook() {
// Delete the site_icon
if ( isset( $GLOBALS['plugin_page'] ) && 'jetpack-site_icon-upload' == $GLOBALS['plugin_page'] ) {
if ( isset( $_GET['action'] )
&& 'remove' == $_GET['action']
&& isset( $_GET['nonce'] )
&& wp_verify_nonce( $_GET['nonce'], 'remove_site_icon' ) ) {
$site_icon_id = Jetpack_Options::get_option( 'site_icon_id' );
// Delete the previous Blavatar
self::delete_site_icon( $site_icon_id, true );
wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) );
}
}
}
/**
* Add HTML to the General Settings
*/
public function site_icon_settings() {
$upload_blavatar_url = admin_url( 'options-general.php?page=jetpack-site_icon-upload' );
// lets delete the temp data that we might he holding on to
self::delete_temporay_data();
?>
get_error_message() ); ?>
crop( $crop_data['crop_x'], $crop_data['crop_y'],$crop_data['crop_width'], $crop_data['crop_height'], self::$min_size, self::$min_size );
$dir = wp_upload_dir();
$site_icon_filename = $image_edit->generate_filename( dechex ( time() ) . 'v' . self::$version . '_site_icon', null, 'png' );
// If the attachment is a URL, then change it to a local file name to allow us to save and then upload the cropped image
$check_url = parse_url( $site_icon_filename );
if ( isset( $check_url['host'] ) ) {
$upload_dir = wp_upload_dir();
$site_icon_filename = $upload_dir['path'] . '/' . basename( $site_icon_filename );
}
$image_edit->save( $site_icon_filename );
add_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'additional_sizes' ) );
$site_icon_id = self::save_attachment(
__( 'Large Blog Image', 'jetpack' ) ,
$site_icon_filename,
'image/png'
);
remove_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'additional_sizes' ) );
// Save the site_icon data into option
Jetpack_Options::update_option( 'site_icon_id', $site_icon_id );
//Get the site icon URL ready to sync
Jetpack_Options::update_option( 'site_icon_url', jetpack_site_icon_url( get_current_blog_id(), 512 ) );
?>
height )
if( $resized_width > $resized_height ) {
$init_x = ( self::$page_crop - $resized_height ) / 2;
$init_size = $resized_height;
}
// Portrait format ( height > width )
if( $resized_width < $resized_height ) {
$init_y = ( self::$page_crop - $resized_width ) / 2;
$init_size = $resized_height;
}
// Square height == width
if( $resized_width = $resized_height ) {
$init_size = $resized_height;
}
return array(
'init_x' => $init_x,
'init_y' => $init_y,
'init_size' => $init_size,
'min_size' => $min_crop_size
);
}
/**
* Delete the temporary created data and attachments
*
* @return null
*/
public static function delete_temporay_data() {
// This should autimatically delete the temporary files as well
delete_option( 'site_icon_temp_data' );
}
/**
* Function gets fired when delete_option( 'site_icon_temp_data' ) is run.
*
* @param $option string
* @return null
*/
public static function delete_temp_data( $option ) {
if( 'site_icon_temp_data' == $option ) {
$temp_image_data = get_option( 'site_icon_temp_data' );
remove_action( 'delete_attachment', array( 'Jetpack_Site_Icon', 'delete_attachment_data' ), 10, 1);
wp_delete_attachment( $temp_image_data['large_image_attachment_id'] , true );
wp_delete_attachment( $temp_image_data['resized_image_attacment_id'] , true );
}
return null;
}
/**
* @param $post_id
*/
public static function delete_attachment_data( $post_id ) {
// The user could be deleting the site_icon image
$site_icon_id = Jetpack_Options::get_option( 'site_icon_id' );
if( $site_icon_id && $post_id == $site_icon_id ) {
Jetpack_Options::delete_option( 'site_icon_id' );
Jetpack_Options::delete_option( 'site_icon_url' );
}
// The user could be deleting the temporary images
}
/**
* @param $check
* @param $post_id
* @param $meta_key
* @param $single
*
* @return mixed
*/
public static function delete_attachment_images( $check, $post_id, $meta_key, $single ) {
$site_icon_id = Jetpack_Options::get_option( 'site_icon_id' );
if( $post_id == $site_icon_id && '_wp_attachment_backup_sizes' == $meta_key && true == $single )
add_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) );
return $check;
}
/**
* Delete the blavatar and all the attached data
*
* @param $id
*
* @return mixed
*/
public static function delete_site_icon( $id ) {
// We add the filter to make sure that we also delete all the added images
add_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) );
wp_delete_attachment( $id , true );
remove_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) );
// for good measure also
self::delete_temporay_data();
// Delete the URL from the Jetpack Options array
Jetpack_Options::delete_option( 'site_icon_url' );
return Jetpack_Options::delete_option( 'site_icon_id' );
}
/**
* @param $crop_x
* @param $crop_y
* @param $crop_width
* @param $crop_height
* @param $ratio
*
* @return array
*/
public static function convert_coodiantes_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 ),
);
}
/**
* Handle the uploaded image
*
* @param $uploaded_file
*
* @return mixed
*/
public static function handle_file_upload( $uploaded_file ) {
// check that the image accuallt is a file with size
if( !isset( $uploaded_file ) || ($uploaded_file['size'] <= 0 ) ) {
return new WP_Error( 'broke', __( 'Please upload a file.', 'jetpack' ) );
}
$arr_file_type = wp_check_filetype( basename( $uploaded_file['name'] ) );
$uploaded_file_type = $arr_file_type['type'];
if( ! in_array( $uploaded_file_type, self::$accepted_file_types ) ) {
// Create a temp file which should be deleted at when the scipt stops
return new WP_Error( 'broke', __( 'The file that you uploaded is not an accepted file type. Please try again.', 'jetpack' ) );
}
$image = wp_handle_upload( $uploaded_file, array( 'test_form' => false ) );
if( is_wp_error( $image ) ) {
// this should contain the error message returned from wp_handle_upload
unlink( $image['file'] ); // Lets delete the file since we are not going to be using it
return $image;
}
// Lets try to crop the image into smaller files.
// We will be doing this later so it is better if it fails now.
$image_edit = wp_get_image_editor( $image['file'] );
if ( is_wp_error( $image_edit ) ) {
// this should contain the error message from WP_Image_Editor
unlink( $image['file'] ); // lets delete the file since we are not going to be using it
return $image_edit;
}
$image_size = getimagesize( $image['file'] );
if( $image_size[0] < self::$min_size || $image_size[1] < self::$min_size ) {
if( $image_size[0] < self::$min_size ) {
return new WP_Error( 'broke', sprintf( __( 'The image that you uploaded is smaller than %upx in width.', 'jetpack' ), self::$min_size ) );
}
if( $image_size[1] < self::$min_size ) {
return new WP_Error( 'broke', sprintf( __( 'The image that you uploaded is smaller than %upx in height.', 'jetpack' ), self::$min_size ) );
}
}
// Save the image as an attachment for later use.
$large_attachment_id = self::save_attachment(
__( 'Temporary Large Image for Blog Image', 'jetpack' ) ,
$image['file'],
$uploaded_file_type,
false
);
// Let's resize the image so that the user can easier crop a image that in the admin view
$image_edit->resize( self::$page_crop, self::$page_crop, false );
$dir = wp_upload_dir();
$resized_filename = $image_edit->generate_filename( 'temp', null, null );
$image_edit->save( $resized_filename );
$resized_attach_id = self::save_attachment(
__( 'Temporary Resized Image for Blog Image', 'jetpack' ),
$resized_filename,
$uploaded_file_type,
false
);
$resized_image_size = getimagesize( $resized_filename );
// Save all of this into the the database for that we can work with it later.
update_option( 'site_icon_temp_data', array(
'large_image_attachment_id' => $large_attachment_id,
'large_image_data' => $image_size,
'resized_image_attacment_id' => $resized_attach_id,
'resized_image_data' => $resized_image_size
) );
return wp_get_attachment_image_src( $resized_attach_id, 'full' );
}
/**
* Save Blavatar files to Media Library
*
* @param string $title
* @param string $filename
* @param string $file_type
* @param boolean $generate_meta
* @return int $attactment_id
*/
public static function save_attachment( $title, $file, $file_type, $generate_meta = true ) {
$filename = _wp_relative_upload_path( $file );
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $filename ),
'post_mime_type' => $file_type,
'post_title' => $title,
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $filename );
if( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
}
if( !$generate_meta )
add_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'only_thumbnail_size' ) );
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata( $attachment_id, $file );
wp_update_attachment_metadata( $attachment_id, $attach_data );
if( !$generate_meta ) {
remove_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'only_thumbnail_size' ) );
}
return $attachment_id;
}
/**
* Add additional sizes to be made when creating the site_icon images
*
* @param array $sizes
* @return array
*/
public static function additional_sizes( $sizes ) {
/**
* Filter the different dimensions that a site icon is saved in.
*
* @module site-icon
*
* @since 3.2.0
*
* @param array $site_icon_sizes Sizes available for the Site Icon. Default is array(256, 128, 80, 64, 32, 16).
*/
self::$site_icon_sizes = apply_filters( 'site_icon_image_sizes', self::$site_icon_sizes );
// use a natural sort of numbers
natsort( self::$site_icon_sizes );
self::$site_icon_sizes = array_reverse ( self::$site_icon_sizes );
// ensure that we only resize the image into
foreach( $sizes as $name => $size_array ) {
if( $size_array['crop'] ){
$only_crop_sizes[ $name ] = $size_array;
}
}
foreach( self::$site_icon_sizes as $size ) {
if( $size < self::$min_size ) {
$only_crop_sizes['site_icon-'.$size] = array(
"width" => $size,
"height"=> $size,
"crop" => true,
);
}
}
return $only_crop_sizes;
}
/**
* Helps us delete site_icon images that
*
* @param [type] $sizes [description]
*
* @return array
*/
public static function intermediate_image_sizes( $sizes ) {
/** This filter is documented in modules/site-icon/jetpack-site-icon.php */
self::$site_icon_sizes = apply_filters( 'site_icon_image_sizes', self::$site_icon_sizes );
foreach( self::$site_icon_sizes as $size ) {
$sizes[] = 'site_icon-'.$size;
}
return $sizes;
}
/**
* Only resize the image to thumbnail so we can use
* Use when resizing temporary images. This way we can see the temp image in Media Gallery.
*
* @param array $sizes
* @return array
*/
public static function only_thumbnail_size( $sizes ){
foreach( $sizes as $name => $size_array ) {
if( 'thumbnail' == $name ) {
$only_thumb['thumbnail'] = $size_array;
}
}
return $only_thumb;
}
}
Jetpack_Site_Icon::init();