WordPress.org

Make WordPress Core

Ticket #16434: trac-16434-03.patch

File trac-16434-03.patch, 21.0 KB (added by TomAuger, 5 years ago)

Update includes new API calls to generate the thumbnail IMG tag, verify existence of a custom favicon, and get the favicon file path. Refactoring to some functions from previous patch.

  • wp-admin/favicon-upload.php

     
     1<?php 
     2/** 
     3 * Handles the uploading, cropping and scaling of favicons. 
     4 *  
     5 * @package WordPress 
     6 * @subpackage Administration 
     7 * @since 3.4.1 
     8 */ 
     9 
     10// Bootstrap admin and all its goodies 
     11require_once('admin.php'); 
     12 
     13define( 'FAVICON_SIZE', 32 ); // Width (and height) of the favicon (in pixels) 
     14 
     15/*      Upload is a 2-step process:      
     16 *      1. Process the uploaded file and show the crop UI 
     17 *      2. Manipulate the pixel data, save to PNG and ICO and write to options. 
     18 */ 
     19 
     20if ( isset( $_POST['CROP_AND_SAVE'] ) ) { 
     21        if ( isset( $_POST['attachment_id'] ) && is_numeric( $_POST['attachment_id'] ) ){ 
     22                $image_basename = process_crop_thumbnail( $_POST['attachment_id'] ); 
     23 
     24                if ( is_wp_error( $image_basename ) ) { 
     25                        include_once('./admin-header.php'); 
     26                        echo '<div class="wrap">'; 
     27                                echo '<h2>' . __( 'Image upload error' ) . '</h2>'; 
     28                                echo '<p>' . $image_basename->get_error_message() . '</p>'; 
     29                                echo '<p><a href="' . admin_url( 'options-general.php' ) . '">&laquo;' . __( 'Back to Settings &gt; General' ) . '</a></p>'; 
     30                        echo '</div><!-- .wrap -->'; 
     31                        include_once('./admin-footer.php'); 
     32                } else { 
     33                        foreach ( array( $image_basename . '.png', $image_basename . '.ico' ) as $image_filename ) 
     34                                save_thumbnail_attachment( $image_filename, $attachment_id ); 
     35 
     36                        // And save the basename out to options. 
     37                        update_option( 'sitefavicon', basename( $image_basename ) ); 
     38                         
     39                        /** @TODO need to find a way to notify the user that the process has completed successfully - admin_notices? */ 
     40                        wp_redirect( admin_url( 'options-general.php' ) ); 
     41                }  
     42        } else { 
     43                return new WP_Error( 'attachment_id_missing', 'Form submission error.' ); 
     44        } 
     45} elseif ( isset( $_POST['REMOVE_FAVICON'] ) ) { 
     46        remove_thumbnail(); 
     47} else { 
     48        /** @TODO make sure that we trap for someone just pressing "Upload image" but with no image attached */ 
     49        // Enqueue the JS for the cropper... 
     50        add_action( 'admin_enqueue_scripts', 'enqueue_cropper' ); 
     51        // ...and our own script for populating the crop form 
     52        add_action( 'admin_footer', 'cropping_js', 10,  1); 
     53         
     54        // Process the upload and create the attachment file in the media center 
     55        $image_results = process_thumbnail_upload(); 
     56         
     57        include_once('./admin-header.php'); 
     58         
     59        // hack because image replication isn't fast enough. See https://wpcom.automattic.com/ticket/1294 
     60        sleep( 2 ); 
     61 
     62        echo '<div class="wrap">'; 
     63         
     64        if ( is_wp_error( $image_results ) )  { 
     65                echo '<h2>' . __( 'Image upload error' ) . '</h2>'; 
     66                echo '<p>' . $image_results->get_error_message() . '</p>'; 
     67                echo '<p><a href="' . admin_url( 'options-general.php' ) . '">&laquo;' . __( 'Back to Settings &gt; General' ) . '</a></p>'; 
     68        } else { 
     69                // Image upload successful. 
     70                // Now we can hook in our javascript and provide the width/height of our image as the default crop size 
     71                $crop_size = min( $image_results['width'], $image_results['height'] ); 
     72                echo '<script type="text/javascript">var jcrop_starting_size = ' . $crop_size . '; // Initialize jcrop crop area starting size</script>'; 
     73         
     74                echo '<h2>' . __( 'Crop uploaded image' ) . '</h2>'; 
     75                echo '<p>' . __( 'Choose the part of the image you want to use for your favicon.' ) . '</p>'; 
     76                 
     77                echo '<form id="favicon-crop-form" method="post" action="' . $_SERVER['REQUEST_URI'] . '">'; // Point the form action back to this script 
     78                 
     79                        echo <<<CROP_FORM 
     80                        <input type="hidden" name="x1" id="x1" /> 
     81                        <input type="hidden" name="y1" id="y1" /> 
     82                        <input type="hidden" name="x2" id="x2" /> 
     83                        <input type="hidden" name="y2" id="y2" /> 
     84                        <input type="hidden" name="width" id="width" /> 
     85                        <input type="hidden" name="height" id="height" /> 
     86                        <input type="hidden" name="attachment_id" id="attachment_id" value="{$image_results['attachment_id']}" /> 
     87                        <input type="hidden" name="scaling_factor" id="scaling_factor" value="{$image_results['scaling_factor']}" /> 
     88CROP_FORM; 
     89                 
     90                        echo '<img src="' . $image_results['src'] . '" id="upload" width="' . $image_results['width'] . '" height="' . $image_results['height'] . '" />'; 
     91                 
     92                        echo '<p class="submit"><input type="submit" name="CROP_AND_SAVE" value="' . __( 'Crop image' ) . ' &raquo;" /></p>'; 
     93                echo '</form>'; 
     94        } 
     95         
     96        echo '</div><!-- .wrap -->'; 
     97         
     98        include_once('./admin-footer.php'); 
     99} 
     100 
     101 
     102/** 
     103 * Process the image file upload and return a WP_Error or details about the attachment image file. 
     104 *  
     105 * @return mixed WP_Error | $image_results array  
     106 */ 
     107function process_thumbnail_upload(){ 
     108        $file = wp_handle_upload( $_FILES['avatarfile'], array( 'action' => 'wp_upload_favicon') ); 
     109        if ( isset($file['error']) ) die( $file['error'] ); 
     110         
     111        $url = $file['url']; 
     112        $file = $file['file']; 
     113        $filename = basename($file); 
     114         
     115        // Construct the object array 
     116        $object = array( 
     117                'post_title' => $filename, 
     118                'post_content' => $url, 
     119                'post_mime_type' => 'import', 
     120                'guid' => $url 
     121        ); 
     122 
     123        // Save the data.  Also makes replication work 
     124        $id = wp_insert_attachment($object, $file); 
     125 
     126        // Retrieve the image dimensions 
     127        list( $orig_width, $orig_height, $type, $attr ) = getimagesize( $file ); 
     128         
     129        // Do we need to scale down the image so we can display it nicely in the interactive Crop tool? 
     130        if ( $orig_width > 600 || $orig_height > 600 ) { 
     131                $image = wp_create_thumbnail( $file, 600 ); 
     132                list( $width, $height, $type, $attr ) = getimagesize( $image ); 
     133                 
     134                 // Update the attachment record to reflect the newly-scaled thumbnail image 
     135                $thumb = basename( $image ); 
     136                $metadata = array( 'thumb' => $thumb ); 
     137                wp_update_attachment_metadata( $id, $metadata ); 
     138 
     139                $url = str_replace( basename( $url ), $thumb, $url ); 
     140 
     141                $scaling = $orig_width / $width; 
     142        } else { 
     143                // No scaling required; just copy original values. 
     144                $width = $orig_width; 
     145                $height = $orig_height; 
     146                $scaling = 1; 
     147        } 
     148 
     149        // Check image file format 
     150        $image_type = exif_imagetype( get_attached_file( $id ) ); 
     151        if (! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP ) ) ) 
     152                $error = new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg) or BMP (.bmp) image files for favicons. ' ) ); 
     153         
     154        // return WP_Error or the $image_results array 
     155        if ( $error ){ 
     156                return $error; 
     157        } else { 
     158                return array(  
     159                        'attachment_id' => $id, 
     160                        'src' => $url, 
     161                        'width' => $width, 
     162                        'height' => $height, 
     163                        'scaling_factor' => $scaling 
     164                ); 
     165        } 
     166} 
     167 
     168/** 
     169 * Create PNG and BMP image resources based on the form submission of the cropped thumbnail. 
     170 *  
     171 * @param int $attachment_id The ID of the original attachment's post record. 
     172 * @return mixed WP_Error | Favicon file base name (ie: fully qualified file name without any TLA file extension) 
     173 */ 
     174function process_crop_thumbnail( $attachment_id ){ 
     175        $src_file = get_attached_file( $attachment_id ); 
     176 
     177        // Highly unlikely, but let's check 
     178        if (! file_exists( $src_file ) ) 
     179                return new WP_Error( 'file_missing', __( 'Attachment image file missing (possible save error: check space on web server).' ) ); 
     180 
     181        // Make sure we're still within accepted image types 
     182        $image_type = exif_imagetype( $src_file ); 
     183        if (! $image_type || ! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP ) ) ) 
     184                return new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg) or BMP (.bmp) image files for favicons. ' ) ); 
     185 
     186        // Parse image file bytes 
     187        $src_image = wp_load_image( $src_file ); 
     188        if ( !is_resource($src_image) ) 
     189                return new WP_Error( 'is_not_resource', __( 'Error loading image. You got me: I\'m stumped.' ) );  
     190 
     191        // We crop from the original, not the medium sized, display-only thumbnail 
     192        $src_x = $_POST['x1'] * $_POST['scaling_factor']; 
     193        $src_y = $_POST['y1'] * $_POST['scaling_factor']; 
     194        $src_width = $_POST['width'] * $_POST['scaling_factor']; 
     195        $src_height = $_POST['height'] * $_POST['scaling_factor']; 
     196 
     197        $dst_width = $dst_height = FAVICON_SIZE; 
     198        // Avoid upscaling 
     199        if ( $src_width < $dst_width || $src_height < $dst_height ) { 
     200                $dst_width = $src_width; 
     201                $dst_height = $src_height; 
     202        } 
     203 
     204        $dst_image = wp_imagecreatetruecolor( $dst_width, $dst_height ); 
     205        if (function_exists('imageantialias')) imageantialias($dst_image, true); 
     206        imagealphablending($dst_image, false); 
     207        imagesavealpha($dst_image, true); 
     208        imagecopyresampled($dst_image, $src_image, 0, 0, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height); 
     209        imagedestroy( $src_image ); 
     210 
     211 
     212        // Save the image in PNG and BMP formats 
     213        $file_info = pathinfo( $src_file ); 
     214        $src_basename = basename( $src_file, '.' . $file_info['extension'] ); 
     215        $dst_filename = str_replace( $src_basename, $src_basename . '_' . FAVICON_SIZE . 'x' . FAVICON_SIZE, $src_file ); 
     216        // Strip the TLA from the filename 
     217        $dst_filename = preg_replace( '/\\.[^\\.]+$/', '', $dst_filename ); 
     218 
     219        $png_filename = $dst_filename . '.png'; 
     220        if (! imagepng( $dst_image, $png_filename, 0 ) ) 
     221                return new WP_Error( 'png_write_error', 'Error writing PNG favicon file.' ); 
     222        $ico_filename = $dst_filename . '.ico'; 
     223        if (!image2wbmp( $dst_image, $ico_filename, 1 ) ) 
     224                return new WP_Error( 'ico_write_error', 'Error writing ICO favicon file.' ); 
     225 
     226        imagedestroy($dst_image); 
     227 
     228        return $dst_filename; 
     229} 
     230 
     231/** 
     232 * Creates an attachment post record for a newly created thumbnail 
     233 *  
     234 * @param string $file_name Fully qualified file name for the image asset file. 
     235 * @param int $parent_attachment_id The ID of the original thumbnail's attachment post record 
     236 *  
     237 * @return int The ID of the newly-created thumbnail attachment post record 
     238 */ 
     239function save_thumbnail_attachment( $file_name, $parent_attachment_id ){ 
     240        $file_info = pathinfo( $file_name ); // So we can get the TLA later on 
     241         
     242        $file_name = apply_filters( 'wp_create_file_in_uploads', $file_name, $parent_attachment_id ); // For replication 
     243 
     244        $parent = get_post( $parent_attachment_id ); 
     245        $parent_url = $parent->guid; 
     246         
     247        // Update the attachment 
     248        $mimes = get_allowed_mime_types(); 
     249        $attachment_id = wp_insert_attachment( array( 
     250                'ID' => $attachment_id, 
     251                'post_title' => basename( $file_name ), 
     252                'post_content' => $url, 
     253                'post_mime_type' => $mimes[ $file_info['extension'] ], 
     254                'guid' => $url, 
     255                'context' => 'favicon' 
     256        ), $file_name ); 
     257        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file_name ) ); 
     258         
     259        return $attachment_id; 
     260} 
     261 
     262function remove_thumbnail(){ 
     263         
     264} 
     265 
     266 
     267/** 
     268 * Called in admin_enqueue_scripts to add the cropper.js script and styles 
     269 */ 
     270function enqueue_cropper(){ 
     271        wp_enqueue_script( 'jcrop', 'jquery' ); 
     272        wp_enqueue_style('jcrop'); // We can enqueue styles within the admin_enqueue_script action hook {@link http://wpdevel.wordpress.com/2011/12/12/use-wp_enqueue_scripts-not-wp_print_styles-to-enqueue-scripts-and-styles-for-the-frontend/} 
     273} 
     274 
     275function cropping_js(){ 
     276        // Purely for coding convenience and legibility 
     277        $favicon_size = FAVICON_SIZE; 
     278         
     279        echo <<<CROP_JS 
     280        <!-- Favicon cropping --> 
     281        <script type="text/javascript"> 
     282                // Update the crop form 
     283                function onEndCrop( coords ) { 
     284                        jQuery( '#x1' ).val(coords.x); 
     285                        jQuery( '#y1' ).val(coords.y); 
     286                        jQuery( '#x2' ).val(coords.x2); 
     287                        jQuery( '#y2' ).val(coords.y2); 
     288                        jQuery( '#width' ).val(coords.w); 
     289                        jQuery( '#height' ).val(coords.h); 
     290                } 
     291 
     292                // with a supplied ratio 
     293                jQuery(function($) { 
     294                        if (! jcrop_starting_size) jcrop_starting_size = {$favicon_size}; // jcrop_starting_size should be set in the body once the image has been processed 
     295 
     296                        // Set up default values on the crop form 
     297                        jQuery( '#x1' ).val(0); 
     298                        jQuery( '#y1' ).val(0); 
     299                        jQuery( '#x2' ).val(jcrop_starting_size); 
     300                        jQuery( '#y2' ).val(jcrop_starting_size); 
     301                        jQuery( '#width' ).val(jcrop_starting_size); 
     302                        jQuery( '#height' ).val(jcrop_starting_size); 
     303 
     304                        // Initialize Jcrop 
     305                        $('#upload').Jcrop({ 
     306                                aspectRatio: 1, 
     307                                setSelect: [0, 0, jcrop_starting_size, jcrop_starting_size], 
     308                                onSelect: onEndCrop 
     309                        }); 
     310                }); 
     311        </script> 
     312CROP_JS; 
     313 
     314} 
     315 No newline at end of file 
  • wp-admin/js/wp-favicon.dev.js

     
     1(function($){ 
     2    $('#faviconfile').change(function(){ 
     3        // check the file extention 
     4        if (! $.inArray( $(this).val().split('.').pop().toLowerCase() , /* valid file extentions */ ['gif','png','jpg','jpeg'] ) )  
     5            $('#favicon-invalid-filetype').show(); 
     6        else 
     7        { 
     8            $('#faviconupload').submit(); 
     9        } 
     10    }); 
     11 
     12})(jQuery); 
  • wp-admin/js/wp-favicon.js

     
     1(function($){ 
     2    $('#faviconfile').change(function(){ 
     3        // check the file extention 
     4        if (! $.inArray( $(this).val().split('.').pop().toLowerCase() , /* valid file extentions */ ['gif','png','jpg','jpeg'] ) )  
     5            $('#favicon-invalid-filetype').show(); 
     6        else 
     7        { 
     8            $('#faviconupload').submit(); 
     9        } 
     10    }); 
     11 
     12})(jQuery); 
  • wp-admin/options-general.php

     
    8181        '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>' 
    8282); 
    8383 
     84wp_enqueue_script('wp-favicon'); 
     85 
    8486include('./admin-header.php'); 
    8587?> 
    8688 
     
    8890<?php screen_icon(); ?> 
    8991<h2><?php echo esc_html( $title ); ?></h2> 
    9092 
     93<form action="<?php echo admin_url('favicon-upload.php')?>" method="post" enctype="multipart/form-data" id="faviconupload"> 
     94        <input type="hidden" name="action" value="wp_upload_favicon" /> 
     95 
     96        <table class="form-table"> 
     97                <tr valign="top"> 
     98                        <th scope="row"><label for="sitefavicon"><?php _e('Favicon') ?></label></th> 
     99                        <td> 
     100                                <?php 
     101                                        // display the icon and the remove link if appropriate 
     102                                        if ( has_custom_favicon() ){ 
     103                                                if ( $thumbnail = get_favicon_thumbnail_img() ) echo $thumbnail; 
     104                                        } 
     105                                 
     106                                ?> 
     107                                <input class="button" name="avatarfile" type="file" id="faviconfile" size="20" /> 
     108                                <p class="submit no-js hide-if-js"><input type="submit" name="Submit" value="Upload Image &raquo;" id="faviconsubmit" /></p> 
     109                                <span class="description no-js"><?php _e('Click to upload your own custom icon ("favicon") for your blog. You\'ll be able to crop and scale it once it\'s uploaded.') ?></span> 
     110                        </td> 
     111                </tr> 
     112        </table> 
     113</form> 
     114 
    91115<form method="post" action="options.php"> 
    92116<?php settings_fields('general'); ?> 
    93117 
  • wp-includes/functions.php

     
    18451845                'png' => 'image/png', 
    18461846                'bmp' => 'image/bmp', 
    18471847                'tif|tiff' => 'image/tiff', 
    1848                 'ico' => 'image/x-icon', 
     1848                'ico' => 'image/vnd.microsoft.icon', 
    18491849                'asf|asx|wax|wmv|wmx' => 'video/asf', 
    18501850                'avi' => 'video/avi', 
    18511851                'divx' => 'video/divx', 
  • wp-includes/general-template.php

     
    15871587} 
    15881588 
    15891589/** 
     1590 * Convenience function that echoes the HTML for the site's favicon icon. 
     1591 * By default, automatically included in the header via the 'wp_head' action, which can be removed by themes if a custom favicon is desired. 
     1592 *  
     1593 * @uses generate_site_favicon_html() to do the actual heavy lifting 
     1594 */ 
     1595function site_favicon(){ 
     1596        echo generate_site_favicon_html(); 
     1597} 
     1598add_action( 'wp_head', 'site_favicon' ); 
     1599add_action( 'admin_head', 'site_favicon' ); 
     1600 
     1601/** 
     1602 * Return the HTML for the site's favicon icon, if such has been defined. 
     1603 *  
     1604 * @uses get_site_favicon_uri(); 
     1605 *  
     1606 * Includes the conditional tag wrapper for an IE (.ico) version.  
     1607 */ 
     1608function generate_site_favicon_html() { 
     1609        $ie_favicon_uri = get_site_favicon_uri( 'ico' ); 
     1610        $favicon_uri = get_site_favicon_uri(); 
     1611 
     1612        $content = ""; 
     1613        if (! is_wp_error( $ie_favicon_uri ) && ! is_wp_error( $favicon_uri ) ){ 
     1614 
     1615                $content .= <<<FAVICON_HTML 
     1616<!--Favicon (via 'wp_head' action) --> 
     1617<!--[if IE]> 
     1618<link rel="shortcut icon" href="{$ie_favicon_uri}" /> 
     1619<![endif]--> 
     1620<!--[if !IE]>--> 
     1621<link href="{$favicon_uri}" rel="icon" type="image/png" /> 
     1622<!--<![endif]--> 
     1623FAVICON_HTML; 
     1624    } 
     1625        return $content; 
     1626} 
     1627 
     1628/** 
     1629 * Get the attachment post object associated with the current site favicon, based on the 'sitefavicon' option 
     1630 *  
     1631 * @param string $format Default 'png'. Format of the file we're looking for 
     1632 * @return object If found, returns the post object; if not, a WP_Error object 
     1633 */ 
     1634function get_site_favicon_attachment( $format = 'png' ){ 
     1635        $favicon_basename = get_option ( 'sitefavicon' );  
     1636         
     1637        if ( ! empty( $favicon_basename ) ) { 
     1638                $favicon_fullname = $favicon_basename . '-' . $format; 
     1639                 
     1640                $posts = get_posts( array( 'name' => $favicon_fullname, 'post_type' => 'attachment' ) ); 
     1641                if ( $posts[0] ){ 
     1642                        return $posts[0]; 
     1643                } else { 
     1644                        return new WP_Error( 'attachment_missing', __( "No attachment for '$favicon_fullname' was found." ) ); 
     1645                } 
     1646        } else { 
     1647                return new WP_Error( 'not_defined', __( "No favicon file provided." ) ); 
     1648        } 
     1649} 
     1650 
     1651/** 
     1652 * Returns the URI for the site's favicon based on the option set in  Admin > Settings > General. 
     1653 *  
     1654 * @param string $format png|ico default 'png'. Use 'ico' for serving up an IE-compatible ICO file 
     1655 * @return string fully qualified URI  
     1656 */ 
     1657function get_site_favicon_uri( $format = 'png' ){ 
     1658        /** @TODO provide error checking for validity of $format and $size */ 
     1659        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1660         
     1661        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1662        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1663                return wp_get_attachment_url( $favicon_attachment->ID ); 
     1664        } 
     1665         
     1666        // We get here because of an error condition 
     1667        /** @TODO default to the theme's favicon **/ 
     1668        // ATM do nothing (so URI is blank, rather than a WP_Error) 
     1669} 
     1670 
     1671/** 
     1672 * Gets the path to the favicon file, or returns a WP_Error 
     1673 * @param string $format Default 'png' 
     1674 * @return mixed File string or WP_Error object  
     1675 */ 
     1676function get_site_favicon_file( $format = 'png' ){ 
     1677        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1678         
     1679        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1680        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1681                return get_attached_file( $favicon_attachment->ID ); 
     1682        } else { 
     1683                return $favicon_attachment; // returns the WP_Error object 
     1684        } 
     1685} 
     1686 
     1687/** 
     1688 * Returns true or false depending on whether a custom favicon has been defined in Admin 
     1689 * @return boolean  
     1690 */ 
     1691function has_custom_favicon(){ 
     1692        $favicon_basename = get_option ( 'sitefavicon' );  
     1693        /** @TODO more robust checking: don't just check that the option has been set: check that the file exists */ 
     1694        return ( ! empty( $favicon_basename ) ); 
     1695} 
     1696 
     1697/** 
     1698 * Returns an HTML <img> tag populated with the site favicon, in the format specified (usually PNG) 
     1699 * @param string $format Default 'png'. Valid values are 'png', 'bmp' (note 'ico' is NOT valid) 
     1700 * @return mixed Returns HTML <img> tag or WP_Error if invalid format given. Returns nothing if the file is missing.  
     1701 */ 
     1702function get_favicon_thumbnail_img( $format = 'png' ){ 
     1703        if (in_array( strtolower( $format ), array( 'png', 'bmp' ) ) ){ 
     1704                // Does the file actually exist? 
     1705                $file = get_site_favicon_file( $format ); 
     1706                if (! is_wp_error( $file ) && file_exists( $file ) ){ 
     1707                        $src = get_site_favicon_uri( $format ); 
     1708                        if (!is_wp_error( $src ) ){ 
     1709                                return '<img src="' . $src . '" alt="' . _x( 'Site favicon thumbnail', 'Thumbnail image accessibility text' ) .'" />'; 
     1710                        } 
     1711                } 
     1712        } else { 
     1713                return new WP_Error( 'invalid_file_format', __( 'Invalid file format. Valid formats are "png", "bmp".' ) ); 
     1714        } 
     1715} 
     1716 
     1717/** 
    15901718 * Display the links to the general feeds. 
    15911719 * 
    15921720 * @since 2.8.0 
  • wp-includes/script-loader.php

     
    8888 
    8989        $scripts->add( 'wp-fullscreen', "/wp-admin/js/wp-fullscreen$suffix.js", array('jquery'), false, 1 ); 
    9090 
     91        $scripts->add( 'wp-favicon', "/wp-admin/js/wp-favicon$suffix.js", array('jquery'), false, 1 ); 
     92 
    9193        $scripts->add( 'prototype', '/wp-includes/js/prototype.js', array(), '1.6.1'); 
    9294 
    9395        $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array('jquery'), false, 1 );