mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-22 09:07:59 +01:00
Introducing Site Icon, favicon management for WordPress.
This v1 marries Jetpack's Site Icon module with the Media Modal, reusing code from the Custom Header admin. For now, the core-provided icons will be limited to a favicon, an iOS app icon, and a Windows tile icon, leaving `.ico` support and additional icons to plugins to add. Props obenland, tyxla, flixos90, jancbeck, markjaquith, scruffian. See #16434. Built from https://develop.svn.wordpress.org/trunk@32994 git-svn-id: http://core.svn.wordpress.org/trunk@32965 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
2a35e075d7
commit
c56a8ae0f7
57
wp-admin/css/site-icon-rtl.css
Normal file
57
wp-admin/css/site-icon-rtl.css
Normal file
@ -0,0 +1,57 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
28.0 - Site Icon
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
.site-icon-image {
|
||||
float: right;
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.site-icon-content {
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-icon-crop-shell {
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-shell {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-shell h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.site-icon-crop-favicon-preview-shell {
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-favicon,
|
||||
.site-icon-browser-title {
|
||||
height: 16px;
|
||||
right: 88px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-favicon {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.site-icon-browser-title {
|
||||
right: 109px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-homeicon {
|
||||
-webkit-border-radius: 16px;
|
||||
border-radius: 16px;
|
||||
height: 64px;
|
||||
overflow: hidden;
|
||||
width: 64px;
|
||||
}
|
57
wp-admin/css/site-icon.css
Normal file
57
wp-admin/css/site-icon.css
Normal file
@ -0,0 +1,57 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
28.0 - Site Icon
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
.site-icon-image {
|
||||
float: left;
|
||||
margin: 0 20px 0 0;
|
||||
}
|
||||
|
||||
.site-icon-content {
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-icon-crop-shell {
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-shell {
|
||||
float: right;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-shell h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.site-icon-crop-favicon-preview-shell {
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-favicon,
|
||||
.site-icon-browser-title {
|
||||
height: 16px;
|
||||
left: 88px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-favicon {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.site-icon-browser-title {
|
||||
left: 109px;
|
||||
}
|
||||
|
||||
.site-icon-crop-preview-homeicon {
|
||||
-webkit-border-radius: 16px;
|
||||
border-radius: 16px;
|
||||
height: 64px;
|
||||
overflow: hidden;
|
||||
width: 64px;
|
||||
}
|
@ -10,4 +10,5 @@
|
||||
@import url(about-rtl.css);
|
||||
@import url(nav-menus-rtl.css);
|
||||
@import url(widgets-rtl.css);
|
||||
@import url(site-icon-rtl.css);
|
||||
@import url(l10n-rtl.css);
|
||||
|
2
wp-admin/css/wp-admin-rtl.min.css
vendored
2
wp-admin/css/wp-admin-rtl.min.css
vendored
File diff suppressed because one or more lines are too long
@ -10,4 +10,5 @@
|
||||
@import url(about.css);
|
||||
@import url(nav-menus.css);
|
||||
@import url(widgets.css);
|
||||
@import url(site-icon.css);
|
||||
@import url(l10n.css);
|
||||
|
2
wp-admin/css/wp-admin.min.css
vendored
2
wp-admin/css/wp-admin.min.css
vendored
File diff suppressed because one or more lines are too long
BIN
wp-admin/images/browser.png
Normal file
BIN
wp-admin/images/browser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -64,6 +64,9 @@ require_once(ABSPATH . 'wp-admin/includes/theme.php');
|
||||
/** WordPress User Administration API */
|
||||
require_once(ABSPATH . 'wp-admin/includes/user.php');
|
||||
|
||||
/** WordPress Site Icon API */
|
||||
require_once(ABSPATH . 'wp-admin/includes/site-icon.php');
|
||||
|
||||
/** WordPress Update Administration API */
|
||||
require_once(ABSPATH . 'wp-admin/includes/update.php');
|
||||
|
||||
|
636
wp-admin/includes/site-icon.php
Normal file
636
wp-admin/includes/site-icon.php
Normal file
@ -0,0 +1,636 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WP_Site_Icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
class WP_Site_Icon {
|
||||
|
||||
/**
|
||||
* The minimum size of the site icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
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(
|
||||
/**
|
||||
* Square, medium sized tiles for IE11+.
|
||||
*
|
||||
* @link https://msdn.microsoft.com/library/dn455106(v=vs.85).aspx
|
||||
*/
|
||||
270,
|
||||
|
||||
/**
|
||||
* App icons up to iPhone 6 Plus.
|
||||
*
|
||||
* @link https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
|
||||
*/
|
||||
180,
|
||||
|
||||
// Our regular Favicon.
|
||||
32,
|
||||
);
|
||||
|
||||
/**
|
||||
* Register our actions and filters.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// Add the favicon to the backend.
|
||||
add_action( 'admin_head', 'wp_site_icon' );
|
||||
|
||||
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( "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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the site_icon form to upload the image.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function select_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 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-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
|
||||
}
|
||||
|
||||
/**
|
||||
* Crop a the image admin view.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function crop_page() {
|
||||
check_admin_referer( 'crop-site-icon' );
|
||||
|
||||
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 );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Let's resize the image so that the user can easier crop a image that in the admin view.
|
||||
$crop_height = absint( $this->page_crop * $image_size[1] / $image_size[0] );
|
||||
$cropped = wp_crop_image( $attachment_id, 0, 0, 0, 0, $this->page_crop, $crop_height );
|
||||
if ( ! $cropped || is_wp_error( $cropped ) ) {
|
||||
wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) );
|
||||
}
|
||||
$cropped_size = getimagesize( $cropped );
|
||||
|
||||
// set default values (in case of no JS)
|
||||
$crop_ratio = $image_size[0] / $cropped_size[0];
|
||||
if ( $cropped_size[0] < $cropped_size[1] ) {
|
||||
$crop_x = 0;
|
||||
$crop_y = absint( ( $cropped_size[1] - $cropped_size[0] ) / 2 );
|
||||
$crop_size = $cropped_size[0];
|
||||
} elseif ( $cropped_size[0] > $cropped_size[1] ) {
|
||||
$crop_x = absint( ( $cropped_size[0] - $cropped_size[1] ) / 2 );
|
||||
$crop_y = 0;
|
||||
$crop_size = $cropped_size[1];
|
||||
} else {
|
||||
$crop_x = 0;
|
||||
$crop_y = 0;
|
||||
$crop_size = $cropped_size[0];
|
||||
}
|
||||
|
||||
wp_delete_file( $cropped );
|
||||
|
||||
wp_localize_script( 'site-icon-crop', 'wpSiteIconCropData', $this->initial_crop_data( $crop_ratio, $cropped_size ) );
|
||||
?>
|
||||
|
||||
<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>
|
||||
|
||||
<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( $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( $url ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' ); ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<img src="<?php echo esc_url( $url ); ?>" id="crop-image" class="site-icon-crop-image" width="<?php echo esc_attr( $cropped_size[0] ); ?>" height="<?php echo esc_attr( $cropped_size[1] ); ?>" alt="<?php esc_attr_e( 'Image to be cropped' ); ?>"/>
|
||||
|
||||
<input type="hidden" id="crop-x" name="crop-x" value="<?php echo esc_attr( $crop_x ); ?>" />
|
||||
<input type="hidden" id="crop-y" name="crop-y" value="<?php echo esc_attr( $crop_y ); ?>" />
|
||||
<input type="hidden" id="crop-width" name="crop-w" value="<?php echo esc_attr( $crop_size ); ?>" />
|
||||
<input type="hidden" id="crop-height" name="crop-h" value="<?php echo esc_attr( $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.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function set_site_icon() {
|
||||
check_admin_referer( 'set-site-icon' );
|
||||
|
||||
// Delete any existing site icon images.
|
||||
$this->delete_site_icon();
|
||||
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
|
||||
// TODO
|
||||
if ( empty( $_POST['skip-cropping'] ) ) {
|
||||
$crop_ratio = (float) $_POST['crop_ratio'];
|
||||
$crop_data = $this->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->min_size, $this->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->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, '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' );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 initial_crop_data( $ratio, $cropped_size ) {
|
||||
$init_x = $init_y = $init_size = 0;
|
||||
|
||||
$min_crop_size = ( $this->min_size / $ratio );
|
||||
$resized_width = $cropped_size[0];
|
||||
$resized_height = $cropped_size[1];
|
||||
|
||||
// Landscape format ( width > height )
|
||||
if ( $resized_width > $resized_height ) {
|
||||
$init_x = ( $this->page_crop - $resized_height ) / 2;
|
||||
$init_size = $resized_height;
|
||||
}
|
||||
|
||||
// Portrait format ( height > width )
|
||||
if ( $resized_width < $resized_height ) {
|
||||
$init_y = ( $this->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,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional sizes to be made when creating the site_icon images.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $sizes
|
||||
* @return array
|
||||
*/
|
||||
public function additional_sizes( $sizes = array() ) {
|
||||
$only_crop_sizes = array();
|
||||
|
||||
/**
|
||||
* Filter the different dimensions that a site icon is saved in.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $site_icon_sizes Sizes available for the Site Icon.
|
||||
*/
|
||||
$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
|
||||
|
||||
// Use a natural sort of numbers.
|
||||
natsort( $this->site_icon_sizes );
|
||||
$this->site_icon_sizes = array_reverse( $this->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 ( $this->site_icon_sizes as $size ) {
|
||||
if ( $size < $this->min_size ) {
|
||||
$only_crop_sizes[ 'site_icon-' . $size ] = array(
|
||||
'width ' => $size,
|
||||
'height' => $size,
|
||||
'crop' => true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['wp_site_icon'] = new WP_Site_Icon;
|
@ -1778,13 +1778,17 @@ function _media_states( $post ) {
|
||||
$media_states[] = __( 'Background Image' );
|
||||
}
|
||||
|
||||
if ( $post->ID == get_option( 'site_icon' ) ) {
|
||||
$media_states[] = __( 'Site Icon' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the default media display states for items in the Media list table.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param array $media_states An array of media states. Default 'Header Image',
|
||||
* 'Background Image'.
|
||||
* 'Background Image', 'Site Icon'.
|
||||
*/
|
||||
$media_states = apply_filters( 'display_media_states', $media_states );
|
||||
|
||||
|
54
wp-admin/js/site-icon-crop.js
Normal file
54
wp-admin/js/site-icon-crop.js
Normal file
@ -0,0 +1,54 @@
|
||||
/* global wpSiteIconCropData, jQuery */
|
||||
(function($) {
|
||||
var jcrop_api = {},
|
||||
siteIconCrop = {
|
||||
|
||||
updateCoords : function ( coords ) {
|
||||
$( '#crop-x' ).val( coords.x );
|
||||
$( '#crop-y' ).val( coords.y );
|
||||
$( '#crop-width' ).val( coords.w );
|
||||
$( '#crop-height' ).val( coords.h );
|
||||
|
||||
siteIconCrop.showPreview( coords );
|
||||
},
|
||||
|
||||
showPreview : function( coords ){
|
||||
var rx = 64 / coords.w,
|
||||
ry = 64 / coords.h,
|
||||
preview_rx = 16 / coords.w,
|
||||
preview_ry = 16 / coords.h,
|
||||
$cropImage = $( '#crop-image' ),
|
||||
$homeIcon = $( '#preview-homeicon' ),
|
||||
$favicon = $( '#preview-favicon' );
|
||||
|
||||
$homeIcon.css({
|
||||
width: Math.round(rx * $cropImage.attr( 'width' ) ) + 'px',
|
||||
height: Math.round(ry * $cropImage.attr( 'height' ) ) + 'px',
|
||||
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
|
||||
marginTop: '-' + Math.round(ry * coords.y) + 'px'
|
||||
});
|
||||
|
||||
$favicon.css({
|
||||
width: Math.round( preview_rx * $cropImage.attr( 'width' ) ) + 'px',
|
||||
height: Math.round( preview_ry * $cropImage.attr( 'height' ) ) + 'px',
|
||||
marginLeft: '-' + Math.round( preview_rx * coords.x ) + 'px',
|
||||
marginTop: '-' + Math.floor( preview_ry* coords.y ) + 'px'
|
||||
});
|
||||
},
|
||||
|
||||
ready: function() {
|
||||
jcrop_api = $.Jcrop( '#crop-image' );
|
||||
jcrop_api.setOptions({
|
||||
aspectRatio: 1,
|
||||
onSelect: siteIconCrop.updateCoords,
|
||||
onChange: siteIconCrop.updateCoords,
|
||||
minSize: [ wpSiteIconCropData.min_size, wpSiteIconCropData.min_size ]
|
||||
});
|
||||
jcrop_api.animateTo([wpSiteIconCropData.init_x, wpSiteIconCropData.init_y, wpSiteIconCropData.init_size, wpSiteIconCropData.init_size]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
siteIconCrop.ready();
|
||||
|
||||
})(jQuery);
|
1
wp-admin/js/site-icon-crop.min.js
vendored
Normal file
1
wp-admin/js/site-icon-crop.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(a){var b={},c={updateCoords:function(b){a("#crop-x").val(b.x),a("#crop-y").val(b.y),a("#crop-width").val(b.w),a("#crop-height").val(b.h),c.showPreview(b)},showPreview:function(b){var c=64/b.w,d=64/b.h,e=16/b.w,f=16/b.h,g=a("#crop-image"),h=a("#preview-homeicon"),i=a("#preview-favicon");h.css({width:Math.round(c*g.attr("width"))+"px",height:Math.round(d*g.attr("height"))+"px",marginLeft:"-"+Math.round(c*b.x)+"px",marginTop:"-"+Math.round(d*b.y)+"px"}),i.css({width:Math.round(e*g.attr("width"))+"px",height:Math.round(f*g.attr("height"))+"px",marginLeft:"-"+Math.round(e*b.x)+"px",marginTop:"-"+Math.floor(f*b.y)+"px"})},ready:function(){b=a.Jcrop("#crop-image"),b.setOptions({aspectRatio:1,onSelect:c.updateCoords,onChange:c.updateCoords,minSize:[wpSiteIconCropData.min_size,wpSiteIconCropData.min_size]}),b.animateTo([wpSiteIconCropData.init_x,wpSiteIconCropData.init_y,wpSiteIconCropData.init_size,wpSiteIconCropData.init_size])}};c.ready()}(jQuery);
|
49
wp-admin/js/site-icon.js
Normal file
49
wp-admin/js/site-icon.js
Normal file
@ -0,0 +1,49 @@
|
||||
(function($) {
|
||||
var frame;
|
||||
|
||||
$( function() {
|
||||
// Build the choose from library frame.
|
||||
$( '#choose-from-library-link' ).click( function( event ) {
|
||||
var $el = $(this);
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media.frames.customHeader = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: $el.data('choose'),
|
||||
|
||||
// Tell the modal to show only images.
|
||||
library: {
|
||||
type: 'image'
|
||||
},
|
||||
|
||||
// Customize the submit button.
|
||||
button: {
|
||||
// Set the text of the button.
|
||||
text: $el.data('update'),
|
||||
// Tell the button not to close the modal, since we're
|
||||
// going to refresh the page when the image is selected.
|
||||
close: false
|
||||
}
|
||||
});
|
||||
|
||||
// When an image is selected, run a callback.
|
||||
frame.on( 'select', function() {
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get('selection').first(),
|
||||
link = $el.data('updateLink');
|
||||
|
||||
// Tell the browser to navigate to the crop step.
|
||||
window.location = link + '&file=' + attachment.id;
|
||||
});
|
||||
|
||||
frame.open();
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
1
wp-admin/js/site-icon.min.js
vendored
Normal file
1
wp-admin/js/site-icon.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(a){var b;a(function(){a("#choose-from-library-link").click(function(c){var d=a(this);return c.preventDefault(),b?void b.open():(b=wp.media.frames.customHeader=wp.media({title:d.data("choose"),library:{type:"image"},button:{text:d.data("update"),close:!1}}),b.on("select",function(){var a=b.state().get("selection").first(),c=d.data("updateLink");window.location=c+"&file="+a.id}),void b.open())})})}(jQuery);
|
@ -124,6 +124,48 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
|
||||
<td><input name="blogdescription" type="text" id="blogdescription" aria-describedby="tagline-description" value="<?php form_option('blogdescription'); ?>" class="regular-text" />
|
||||
<p class="description" id="tagline-description"><?php _e( 'In a few words, explain what this site is about.' ) ?></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="site_icon"><?php _e( 'Site Icon' ); ?></label></th>
|
||||
<td>
|
||||
<?php
|
||||
$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',
|
||||
), wp_nonce_url( admin_url( 'options-general.php' ), 'crop-site-icon' ) ) );
|
||||
|
||||
wp_enqueue_media();
|
||||
wp_enqueue_script( 'site-icon' );
|
||||
|
||||
if ( has_site_icon() ) :
|
||||
$remove_url = add_query_arg( array(
|
||||
'action' => 'remove_site_icon',
|
||||
), wp_nonce_url( admin_url( 'options-general.php' ), 'remove-site-icon' ) );
|
||||
?>
|
||||
|
||||
<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-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">
|
||||
<a href="<?php echo esc_url( $upload_url ); ?>" class="button"><?php _e( 'Update Site Icon' ); ?></a>
|
||||
<a href="<?php echo esc_url( $remove_url ); ?>"><?php _e( 'Remove Site Icon' ); ?></a>
|
||||
</p>
|
||||
|
||||
<?php else : ?>
|
||||
|
||||
<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-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>
|
||||
|
||||
<?php endif; ?>
|
||||
<p class="description"><?php _e( 'Site Icon creates a favicon and app icons for your site.' ) ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ( !is_multisite() ) { ?>
|
||||
<tr>
|
||||
<th scope="row"><label for="siteurl"><?php _e('WordPress Address (URL)') ?></label></th>
|
||||
|
@ -72,7 +72,7 @@ if ( is_multisite() && !is_super_admin() && 'update' != $action )
|
||||
wp_die( __( 'Cheatin’ uh?' ), 403 );
|
||||
|
||||
$whitelist_options = array(
|
||||
'general' => array( 'blogname', 'blogdescription', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'timezone_string', 'WPLANG' ),
|
||||
'general' => array( 'blogname', 'blogdescription', 'site_icon', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'timezone_string', 'WPLANG' ),
|
||||
'discussion' => array( 'default_pingback_flag', 'default_ping_status', 'default_comment_status', 'comments_notify', 'moderation_notify', 'comment_moderation', 'require_name_email', 'comment_whitelist', 'comment_max_links', 'moderation_keys', 'blacklist_keys', 'show_avatars', 'avatar_rating', 'avatar_default', 'close_comments_for_old_posts', 'close_comments_days_old', 'thread_comments', 'thread_comments_depth', 'page_comments', 'comments_per_page', 'default_comments_page', 'comment_order', 'comment_registration' ),
|
||||
'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type' ),
|
||||
'reading' => array( 'posts_per_page', 'posts_per_rss', 'rss_use_excerpt', 'show_on_front', 'page_on_front', 'page_for_posts', 'blog_public' ),
|
||||
|
@ -222,8 +222,9 @@ add_action( 'wp_head', 'wp_print_styles', 8 );
|
||||
add_action( 'wp_head', 'wp_print_head_scripts', 9 );
|
||||
add_action( 'wp_head', 'wp_generator' );
|
||||
add_action( 'wp_head', 'rel_canonical' );
|
||||
add_action( 'wp_footer', 'wp_print_footer_scripts', 20 );
|
||||
add_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 );
|
||||
add_action( 'wp_head', 'wp_site_icon', 99 );
|
||||
add_action( 'wp_footer', 'wp_print_footer_scripts', 20 );
|
||||
add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 );
|
||||
add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
|
||||
add_action( 'init', 'check_theme_switched', 99 );
|
||||
@ -243,6 +244,11 @@ foreach ( array( 'rss2_head', 'commentsrss2_head', 'rss_head', 'rdf_header', 'at
|
||||
add_action( $action, 'the_generator' );
|
||||
}
|
||||
|
||||
// Feed Site Icon
|
||||
add_action( 'atom_head', 'atom_site_icon' );
|
||||
add_action( 'rss2_head', 'rss2_site_icon' );
|
||||
|
||||
|
||||
// WP Cron
|
||||
if ( !defined( 'DOING_CRON' ) )
|
||||
add_action( 'init', 'wp_cron' );
|
||||
|
@ -587,6 +587,42 @@ function prep_atom_text_construct($data) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Site Icon in atom feeds.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
function atom_site_icon() {
|
||||
$url = get_site_icon_url( null, 32 );
|
||||
if ( $url ) {
|
||||
echo "<icon>$url</icon>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Site Icon in RSS2.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
function rss2_site_icon() {
|
||||
$rss_title = get_wp_title_rss();
|
||||
if ( empty( $rss_title ) ) {
|
||||
$rss_title = get_bloginfo_rss( 'name' );
|
||||
}
|
||||
|
||||
$url = get_site_icon_url( null, 32 );
|
||||
if ( $url ) {
|
||||
echo '
|
||||
<image>
|
||||
<url>' . convert_chars( $url ) . '</url>
|
||||
<title>' . $rss_title . '</title>
|
||||
<link>' . get_bloginfo_rss( 'url' ) . '</link>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</image> ' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the link for the currently displayed feed in a XSS safe way.
|
||||
*
|
||||
|
@ -3421,6 +3421,7 @@ function sanitize_option( $option, $value ) {
|
||||
case 'thread_comments_depth':
|
||||
case 'users_can_register':
|
||||
case 'start_of_week':
|
||||
case 'site_icon':
|
||||
$value = absint( $value );
|
||||
break;
|
||||
|
||||
|
@ -721,6 +721,58 @@ function get_bloginfo( $show = '', $filter = 'raw' ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Site Icon URL.
|
||||
*
|
||||
* @param null|int $blog_id Id of the blog to get the site icon for.
|
||||
* @param int $size Size of the site icon.
|
||||
* @param string $url Fallback url if no site icon is found.
|
||||
* @return string Site Icon URL.
|
||||
*/
|
||||
function get_site_icon_url( $blog_id = null, $size = 512, $url = '' ) {
|
||||
if ( function_exists( 'get_blog_option' ) ) {
|
||||
if ( ! is_int( $blog_id ) ) {
|
||||
$blog_id = get_current_blog_id();
|
||||
}
|
||||
$site_icon_id = get_blog_option( $blog_id, 'site_icon' );
|
||||
} else {
|
||||
$site_icon_id = get_option( 'site_icon' );
|
||||
}
|
||||
|
||||
if ( $site_icon_id ) {
|
||||
if ( $size >= 512 ) {
|
||||
$size_data = 'full';
|
||||
} else {
|
||||
$size_data = array( $size, $size );
|
||||
}
|
||||
$url_data = wp_get_attachment_image_src( $site_icon_id, $size_data );
|
||||
$url = $url_data[0];
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Site Icon URL.
|
||||
*
|
||||
* @param null|int $blog_id Id of the blog to get the site icon for.
|
||||
* @param int $size Size of the site icon.
|
||||
* @param string $url Fallback url if no site icon is found.
|
||||
*/
|
||||
function site_icon_url( $blog_id = null, $size = 512, $url = '' ) {
|
||||
echo esc_url( get_site_icon_url( $blog_id, $size, $url ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the site has a Site Icon.
|
||||
*
|
||||
* @param int|null $blog_id Optional. Blog ID. Default: Current blog.
|
||||
* @return bool
|
||||
*/
|
||||
function has_site_icon( $blog_id = null ) {
|
||||
return !! get_site_icon_url( $blog_id, 512 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display title tag with contents.
|
||||
*
|
||||
@ -2385,6 +2437,39 @@ function wp_no_robots() {
|
||||
echo "<meta name='robots' content='noindex,follow' />\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Display site icon meta tags.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon.
|
||||
*/
|
||||
function wp_site_icon() {
|
||||
if ( ! has_site_icon() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$meta_tags = array(
|
||||
sprintf( '<link rel="icon" href="%s" sizes="32x32" />', esc_url( get_site_icon_url( null, 32 ) ) ),
|
||||
sprintf( '<link rel="apple-touch-icon-precomposed" href="%s">', esc_url( get_site_icon_url( null, 180 ) ) ),
|
||||
sprintf( '<meta name="msapplication-TileImage" content="%s">', esc_url( get_site_icon_url( null, 270 ) ) ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the site icon meta tags, so Plugins can add their own.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $meta_tags Site Icon meta elements.
|
||||
*/
|
||||
$meta_tags = apply_filters( 'site_icon_meta_tags', $meta_tags );
|
||||
$meta_tags = array_filter( $meta_tags );
|
||||
|
||||
foreach ( $meta_tags as $meta_tag ) {
|
||||
echo "$meta_tag\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user should have a WYSIWIG editor.
|
||||
*
|
||||
|
@ -612,6 +612,9 @@ function wp_default_scripts( &$scripts ) {
|
||||
'untitled' => _x( '(no label)', 'missing menu item navigation label' )
|
||||
) );
|
||||
|
||||
$scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery' ), false, 1 );
|
||||
$scripts->add( 'site-icon-crop', '/wp-admin/js/site-icon-crop.js', array( 'jcrop' ), false, 1 );
|
||||
|
||||
$scripts->add( 'custom-header', "/wp-admin/js/custom-header.js", array( 'jquery-masonry' ), false, 1 );
|
||||
$scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 );
|
||||
$scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array('jquery'), false, 1 );
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '4.3-alpha-32993';
|
||||
$wp_version = '4.3-alpha-32994';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
Loading…
Reference in New Issue
Block a user