Jetpack_Site_Icon

Plugin Name: Site Icon Plugin URL: http://wordpress.com/ Description: Add a site icon for your website.

Defined (1)

The class is defined in the following location(s).

/modules/site-icon/jetpack-site-icon.php  
  1. class Jetpack_Site_Icon { 
  2.  
  3. public $module = 'site-icon'; 
  4. public static $version = 1; 
  5. public static $assets_version = 2; 
  6.  
  7. public static $min_size = 512; // the minimum size of the blavatar, 512 is the same as wp.com can be overwritten by SITE_ICON_MIN_SIZE 
  8. public static $page_crop = 512; // the size to which to crop the image so that we can display it in the UI nicely 
  9.  
  10. public static $accepted_file_types = array( 
  11. 'image/jpg',  
  12. 'image/jpeg',  
  13. 'image/gif',  
  14. 'image/png' 
  15. ); 
  16.  
  17. public static $site_icon_sizes = array( 
  18. 256,  
  19. 128,  
  20. 80,  
  21. 64,  
  22. 32,  
  23. 16,  
  24. ); 
  25.  
  26. static $instance = false; 
  27.  
  28. /** 
  29. * Singleton 
  30. */ 
  31. public static function init() { 
  32. if ( ! self::$instance ) { 
  33. self::$instance = new Jetpack_Site_Icon; 
  34. self::$instance->register_hooks(); 
  35.  
  36. return self::$instance; 
  37.  
  38. private function __construct() { 
  39. self::$min_size = ( defined( 'SITE_ICON_MIN_SIZE' ) && is_int( SITE_ICON_MIN_SIZE ) ) ? SITE_ICON_MIN_SIZE : self::$min_size; 
  40.  
  41. /** 
  42. * Register our actions and filters 
  43. * @return null 
  44. */ 
  45. public function register_hooks() { 
  46. add_action( 'jetpack_modules_loaded', array( $this, 'jetpack_modules_loaded' ) ); 
  47. add_action( 'admin_menu', array( $this, 'admin_menu_upload_site_icon' ) ); 
  48. add_filter( 'display_media_states', array( $this, 'add_media_state' ) ); 
  49. add_action( 'admin_init', array( $this, 'admin_init' ) ); 
  50. add_action( 'admin_init', array( $this, 'delete_site_icon_hook' ) ); 
  51.  
  52. add_action( 'admin_print_styles-options-general.php', array( $this, 'add_general_options_styles' ) ); 
  53.  
  54. // Add the favicon to the front end and backend if Core's site icon not used. 
  55. /** 
  56. * As of WP 4.3 and JP 3.6, both are outputting the same icons so no need to fire these. 
  57. * This is a temporary solution until Jetpack's module primary function is deprecated. 
  58. * In the future, Jetpack's can output other sizes using Core's icon. 
  59. */ 
  60. if ( ( function_exists( 'has_site_icon' ) && ! has_site_icon() ) || ! function_exists( 'has_site_icon' ) ) { 
  61. add_action( 'wp_head', array( $this, 'site_icon_add_meta' ) ); 
  62. add_action( 'admin_head', array( $this, 'site_icon_add_meta' ) ); 
  63. add_action( 'atom_head', array( $this, 'atom_icon' ) ); 
  64. add_action( 'rss2_head', array( $this, 'rss2_icon' ) ); 
  65.  
  66. // Check if site icon is available in core, and if so convert Jetpack's to use it. 
  67. add_action( 'admin_init', array( 'Jetpack', 'jetpack_site_icon_available_in_core' ) ); 
  68.  
  69. add_action( 'delete_option', array( 'Jetpack_Site_Icon', 'delete_temp_data' ), 10, 1); // used to clean up after itself. 
  70. add_action( 'delete_attachment', array( 'Jetpack_Site_Icon', 'delete_attachment_data' ), 10, 1); // in case user deletes the attachment via 
  71. add_filter( 'get_post_metadata', array( 'Jetpack_Site_Icon', 'delete_attachment_images' ), 10, 4 ); 
  72.  
  73. /** 
  74. * After all modules have been loaded. 
  75. */ 
  76. public function jetpack_modules_loaded() { 
  77. Jetpack::enable_module_configurable( $this->module ); 
  78. Jetpack::module_configuration_load( $this->module, array( $this, 'jetpack_configuration_load' ) ); 
  79.  
  80. /** 
  81. * Add meta elements to a blog header to light up Blavatar icons recognized by user agents. 
  82. * @link http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon HTML5 specification link icon 
  83. */ 
  84. public function site_icon_add_meta() { 
  85. if ( 
  86. /** 
  87. * Toggles the Favicon meta elements from being loaded. 
  88. * @module site-icon 
  89. * @since 3.2.0 
  90. * @param bool Output Site Icon Meta Elements. 
  91. */ 
  92. apply_filters( 'site_icon_has_favicon', false ) 
  93. ) { 
  94. return; 
  95.  
  96. $url_114 = jetpack_site_icon_url( null, 114 ); 
  97. $url_72 = jetpack_site_icon_url( null, 72 ); 
  98. $url_32 = jetpack_site_icon_url( null, 32 ); 
  99. if( $url_32 ) { 
  100. echo '<link rel="icon" href="'.esc_url( $url_32 ) .'" sizes="32x32" />' . "\n"; 
  101. echo '<link rel="apple-touch-icon-precomposed" href="'. esc_url( $url_114 ) .'">' . "\n"; 
  102. // windows tiles 
  103. echo '<meta name="msapplication-TileImage" content="' . esc_url( $url_114 ) . '"/>' . "\n"; 
  104.  
  105. /** 
  106. * Display icons in RSS2. 
  107. */ 
  108. public function rss2_icon() { 
  109. /** This filter is documented in modules/site-icon/jetpack-site-icon.php */ 
  110. if ( apply_filters( 'site_icon_has_favicon', false ) ) { 
  111. return; 
  112.  
  113. $rss_title = get_wp_title_rss(); 
  114. if ( empty( $rss_title ) ) { 
  115. $rss_title = get_bloginfo_rss( 'name' ); 
  116.  
  117. $icon = jetpack_site_icon_url( null, 32 ); 
  118. if( $icon ) { 
  119. echo ' 
  120. <image> 
  121. <url>' . convert_chars( $icon ) . '</url> 
  122. <title>' . $rss_title . '</title> 
  123. <link>' . get_bloginfo_rss( 'url' ) . '</link> 
  124. <width>32</width> 
  125. <height>32</height> 
  126. </image> '."\n"; 
  127.  
  128. /** 
  129. * Display icons in atom feeds. 
  130. */ 
  131. public function atom_icon() { 
  132. /** This filter is documented in modules/site-icon/jetpack-site-icon.php */ 
  133. if ( apply_filters( 'site_icon_has_favicon', false ) ) { 
  134. return; 
  135.  
  136. $url = jetpack_site_icon_url( null, 32 ); 
  137. if( $url ) { 
  138. echo ' 
  139. <icon>' . $url . '</icon> '."\n"; 
  140.  
  141. /** 
  142. * Add a hidden upload page from people 
  143. */ 
  144. public function admin_menu_upload_site_icon() { 
  145. $page_hook = add_submenu_page( 
  146. null,  
  147. __( 'Site Icon Upload', 'jetpack' ),  
  148. '',  
  149. 'manage_options',  
  150. 'jetpack-site_icon-upload',  
  151. array( $this, 'upload_site_icon_page' ) 
  152. ); 
  153.  
  154. add_action( "admin_head-$page_hook", array( $this, 'upload_balavatar_head' ) ); 
  155.  
  156.  
  157. /** 
  158. * Add styles to the General Settings Screen 
  159. */ 
  160. public function add_general_options_styles() { 
  161. wp_enqueue_style( 'site-icon-admin' ); 
  162. /** 
  163. * Add Styles to the Upload UI Page 
  164. */ 
  165. public function upload_balavatar_head() { 
  166.  
  167. wp_register_script( 'jetpack-site-icon-crop', plugin_dir_url( __FILE__ ). "js/site-icon-crop.js" , array( 'jquery', 'jcrop' ) , self::$assets_version, false); 
  168. if ( isset( $_REQUEST['step'] ) && $_REQUEST['step'] == 2 ) { 
  169. wp_enqueue_script( 'jetpack-site-icon-crop' ); 
  170. wp_enqueue_style( 'jcrop' ); 
  171. wp_enqueue_style( 'site-icon-admin' ); 
  172.  
  173. public function add_media_state( $media_states ) { 
  174.  
  175. if ( jetpack_has_site_icon() ) { 
  176. global $post; 
  177.  
  178. if( $post->ID == Jetpack_Options::get_option( 'site_icon_id' ) ) { 
  179. $media_states[] = __( 'Site Icon', 'jetpack' ); 
  180.  
  181. return $media_states; 
  182.  
  183. /** 
  184. * Direct the user to the Settings -> General 
  185. */ 
  186. public static function jetpack_configuration_load() { 
  187. wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) ); 
  188. exit; 
  189.  
  190. /** 
  191. * Load on when the admin is initialized 
  192. */ 
  193. public function admin_init() { 
  194. /** register the styles and scripts */ 
  195. wp_register_style( 'site-icon-admin' , plugin_dir_url( __FILE__ ). "css/site-icon-admin.css", array(), self::$assets_version ); 
  196. // register the settings 
  197. add_settings_section( 
  198. $this->module,  
  199. '',  
  200. array( $this, 'site_icon_settings' ),  
  201. 'general' 
  202. ); 
  203.  
  204. // We didn't have site_icon_url in 3.2 // this could potentially be removed in a year 
  205. if( get_option( 'site_icon_id' ) && ! Jetpack_Options::get_option( 'site_icon_url' ) ) { 
  206. Jetpack_Options::update_option( 'site_icon_id', get_option( 'site_icon_id' ) ); 
  207. Jetpack_Options::update_option( 'site_icon_url', jetpack_site_icon_url( get_current_blog_id(), 512 ) ); 
  208. delete_option( 'site_icon_id' ); 
  209.  
  210. /** 
  211. * Checks for permission to delete the site_icon 
  212. */ 
  213. public function delete_site_icon_hook() { 
  214. // Delete the site_icon 
  215. if ( isset( $GLOBALS['plugin_page'] ) && 'jetpack-site_icon-upload' == $GLOBALS['plugin_page'] ) { 
  216. if ( isset( $_GET['action'] ) 
  217. && 'remove' == $_GET['action'] 
  218. && isset( $_GET['nonce'] ) 
  219. && wp_verify_nonce( $_GET['nonce'], 'remove_site_icon' ) ) { 
  220.  
  221. $site_icon_id = Jetpack_Options::get_option( 'site_icon_id' ); 
  222. // Delete the previous Blavatar 
  223. self::delete_site_icon( $site_icon_id, true ); 
  224. wp_safe_redirect( admin_url( 'options-general.php#site-icon' ) ); 
  225.  
  226. /** 
  227. * Add HTML to the General Settings 
  228. */ 
  229. public function site_icon_settings() { 
  230. $upload_blavatar_url = admin_url( 'options-general.php?page=jetpack-site_icon-upload' ); 
  231.  
  232. // lets delete the temp data that we might he holding on to 
  233. self::delete_temporay_data(); 
  234.  
  235. ?> 
  236. <div id="site-icon" class="site-icon-shell"> 
  237. <h3><?php echo esc_html_e( 'Site Icon', 'jetpack' ); ?></h3> 
  238. <div class="site-icon-content postbox"> 
  239. <div class="site-icon-image"> 
  240. <?php if( jetpack_has_site_icon() ) { 
  241. echo jetpack_get_site_icon( null, 128 ); 
  242. } ?> 
  243. </div> 
  244. <div class="site-icon-meta"> 
  245.  
  246. <?php if ( jetpack_has_site_icon() ) { 
  247. $remove_blavatar_url = admin_url( 'options-general.php?page=jetpack-site_icon-upload' )."&action=remove&nonce=".wp_create_nonce( 'remove_site_icon' ); // this could be an ajax url 
  248. ?> 
  249. <p><a href="<?php echo esc_url( $upload_blavatar_url ); ?>" id="site-icon-update" class="button"><?php echo esc_html_e( 'Update Site Icon', 'jetpack' ); ?></a> 
  250. <a href="<?php echo esc_url( $remove_blavatar_url ); ?>" id="site-icon-remove" ><?php echo esc_html_e( 'Remove Icon', 'jetpack' ); ?></a> </p> 
  251.  
  252. <?php } else { ?> 
  253.  
  254. <a href="<?php echo esc_url( $upload_blavatar_url ); ?>" id="site-icon-update" class="button"><?php echo esc_html_e( 'Add a Site Icon', 'jetpack' ); ?></a> 
  255.  
  256. <?php } ?> 
  257.  
  258. <div class="site-icon-info"> 
  259. <p><?php echo esc_html_e( 'Site Icon creates a favicon for your site and more.', 'jetpack' ); ?></p> 
  260. </div> 
  261.  
  262. </div> 
  263. </div> 
  264. </div> 
  265. <?php 
  266.  
  267. /** 
  268. * Hidden Upload Blavatar page for people that don't like modals 
  269. */ 
  270. public function upload_site_icon_page() { ?> 
  271. <div class="wrap"> 
  272. <?php require_once( dirname( __FILE__ ) . '/upload-site-icon.php' ); ?> 
  273. </div> 
  274. <?php 
  275.  
  276. /** 
  277. * Select a file admin view 
  278. */ 
  279. public static function select_page() { 
  280. // Display the site_icon form to upload the image 
  281. ?> 
  282. <form action="<?php echo esc_url( admin_url( 'options-general.php?page=jetpack-site_icon-upload' ) ); ?>" method="post" enctype="multipart/form-data"> 
  283.  
  284. <h2 class="site-icon-title"> 
  285. <?php if( jetpack_has_site_icon() ) { 
  286. esc_html_e( 'Update Site Icon', 'jetpack' ); 
  287. } else { 
  288. esc_html_e( 'Add Site Icon', 'jetpack' ); 
  289. } ?> <span class="small"><?php esc_html_e( 'select a file', 'jetpack' ); ?></span></h2> 
  290. <p><?php esc_html_e( 'Upload a image that you want to use as your site icon. You will be asked to crop it in the next step.', 'jetpack' ); ?></p> 
  291.  
  292.  
  293. <p><input name="site-iconfile" id="site-iconfile" type="file" /></p> 
  294. <p><?php esc_html_e( 'The image needs to be at least', 'jetpack' ); ?> <strong><?php echo self::$min_size; ?>px</strong> <?php esc_html_e( 'in both width and height.', 'jetpack' ); ?></p> 
  295. <p class="submit site-icon-submit-form"> 
  296. <input name="submit" value="<?php esc_attr_e( 'Upload Image' , 'jetpack' ); ?>" type="submit" class="button button-primary button-large" /><?php printf( __( ' or <a href="%s">Cancel</a> and go back to the settings.' , 'jetpack' ), esc_url( admin_url( 'options-general.php' ) ) ); ?> 
  297. <input name="step" value="2" type="hidden" /> 
  298.  
  299. <?php wp_nonce_field( 'update-site_icon-2', '_nonce' ); ?> 
  300. </p> 
  301. </form> 
  302. <?php 
  303.  
  304. /** 
  305. * Crop a the image admin view 
  306. */ 
  307. public static function crop_page() { 
  308. // handle the uploaded image 
  309. $image = self::handle_file_upload( $_FILES['site-iconfile'] ); 
  310.  
  311. // display the image image croppping funcunality 
  312. if( is_wp_error( $image ) ) { ?> 
  313. <div id="message" class="updated error below-h2"><p><?php echo esc_html( $image->get_error_message() ); ?></p></div> 
  314. <?php 
  315. // back to step one 
  316. $_POST = array(); 
  317. self::delete_temporay_data(); 
  318. self::select_page(); 
  319. return; 
  320.  
  321. $crop_data = get_option( 'site_icon_temp_data' ); 
  322. $crop_ration = $crop_data['large_image_data'][0] / $crop_data['resized_image_data'][0]; // always bigger then 1 
  323.  
  324. // lets make sure that the Javascript ia also loaded 
  325. wp_localize_script( 'jetpack-site-icon-crop', 'Site_Icon_Crop_Data', self::initial_crop_data( $crop_data['large_image_data'][0] , $crop_data['large_image_data'][1], $crop_data['resized_image_data'][0], $crop_data['resized_image_data'][1] ) ); 
  326. ?> 
  327.  
  328. <h2 class="site-icon-title"><?php esc_html_e( 'Site Icon', 'jetpack' ); ?> <span class="small"><?php esc_html_e( 'crop the image', 'jetpack' ); ?></span></h2> 
  329. <div class="site-icon-crop-shell"> 
  330. <form action="" method="post" enctype="multipart/form-data"> 
  331. <p class="site-icon-submit-form"><input name="submit" value="<?php esc_attr_e( 'Crop Image', 'jetpack' ); ?>" type="submit" class="button button-primary button-large" /><?php printf( __( ' or <a href="%s">Cancel</a> and go back to the settings.' , 'jetpack' ), esc_url( admin_url( 'options-general.php' ) ) ); ?></p> 
  332. <div class="site-icon-crop-preview-shell"> 
  333.  
  334. <h3><?php esc_html_e( 'Preview', 'jetpack' ); ?></h3> 
  335.  
  336. <strong><?php esc_html_e( 'As your favicon', 'jetpack' ); ?></strong> 
  337. <div class="site-icon-crop-favicon-preview-shell"> 
  338. <img src="<?php echo esc_url( plugin_dir_url( __FILE__ ). "browser.png" ); ?>" class="site-icon-browser-preview" width="172" height="79" alt="<?php esc_attr_e( 'Browser Chrome' , 'jetpack' ); ?>" /> 
  339. <div class="site-icon-crop-preview-favicon"> 
  340. <img src="<?php echo esc_url( $image[0] ); ?>" id="preview-favicon" alt="<?php esc_attr_e( 'Preview Favicon' , 'jetpack' ); ?>" /> 
  341. </div> 
  342. <span class="site-icon-browser-title"><?php echo esc_html( get_bloginfo( 'name' ) ); ?></span> 
  343. </div> 
  344.  
  345. <strong><?php esc_html_e( 'As a mobile icon', 'jetpack' ); ?></strong> 
  346. <div class="site-icon-crop-preview-homeicon"> 
  347. <img src="<?php echo esc_url( $image[0] ); ?>" id="preview-homeicon" alt="<?php esc_attr_e( 'Preview Home Icon' , 'jetpack' ); ?>" /> 
  348. </div> 
  349. </div> 
  350. <img src="<?php echo esc_url( $image[0] ); ?>" id="crop-image" class="site-icon-crop-image" 
  351. width="<?php echo esc_attr( $crop_data['resized_image_data'][0] ); ?>" 
  352. height="<?php echo esc_attr( $crop_data['resized_image_data'][1] ); ?>" 
  353. alt="<?php esc_attr_e( 'Image to be cropped', 'jetpack' ); ?>" /> 
  354.  
  355. <input name="step" value="3" type="hidden" /> 
  356. <input type="hidden" id="crop-x" name="crop-x" /> 
  357. <input type="hidden" id="crop-y" name="crop-y" /> 
  358. <input type="hidden" id="crop-width" name="crop-w" /> 
  359. <input type="hidden" id="crop-height" name="crop-h" /> 
  360.  
  361. <?php wp_nonce_field( 'update-site_icon-3', '_nonce' ); ?> 
  362.  
  363. </form> 
  364. </div> 
  365. <?php 
  366. /** 
  367. * All done page admin view 
  368. */ 
  369. public static function all_done_page() { 
  370.  
  371. $temp_image_data = get_option( 'site_icon_temp_data' ); 
  372. if( ! $temp_image_data ) { 
  373. // start again 
  374. self::select_page(); 
  375. return; 
  376. $crop_ration = $temp_image_data['large_image_data'][0] / $temp_image_data['resized_image_data'][0]; // always bigger then 1 
  377.  
  378. $crop_data = self::convert_coodiantes_from_resized_to_full( $_POST['crop-x'], $_POST['crop-y'], $_POST['crop-w'], $_POST['crop-h'], $crop_ration ); 
  379.  
  380. $image_edit = wp_get_image_editor( _load_image_to_edit_path( $temp_image_data['large_image_attachment_id'] ) ); 
  381.  
  382. if ( is_wp_error( $image_edit ) ) { 
  383. return $image_edit; 
  384.  
  385. // Delete the previous site_icon 
  386. $previous_site_icon_id = Jetpack_Options::get_option( 'site_icon_id' ); 
  387. self::delete_site_icon( $previous_site_icon_id ); 
  388.  
  389. // crop the image 
  390. $image_edit->crop( $crop_data['crop_x'], $crop_data['crop_y'], $crop_data['crop_width'], $crop_data['crop_height'], self::$min_size, self::$min_size ); 
  391.  
  392. $dir = wp_upload_dir(); 
  393.  
  394. $site_icon_filename = $image_edit->generate_filename( dechex ( time() ) . 'v' . self::$version . '_site_icon', null, 'png' ); 
  395.  
  396. // 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 
  397. $check_url = parse_url( $site_icon_filename ); 
  398. if ( isset( $check_url['host'] ) ) { 
  399. $upload_dir = wp_upload_dir(); 
  400. $site_icon_filename = $upload_dir['path'] . '/' . basename( $site_icon_filename ); 
  401.  
  402. $image_edit->save( $site_icon_filename ); 
  403.  
  404. add_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'additional_sizes' ) ); 
  405.  
  406. $site_icon_id = self::save_attachment( 
  407. __( 'Large Blog Image', 'jetpack' ) ,  
  408. $site_icon_filename,  
  409. 'image/png' 
  410. ); 
  411.  
  412. remove_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'additional_sizes' ) ); 
  413.  
  414. // Save the site_icon data into option 
  415. Jetpack_Options::update_option( 'site_icon_id', $site_icon_id ); 
  416.  
  417. //Get the site icon URL ready to sync 
  418. Jetpack_Options::update_option( 'site_icon_url', jetpack_site_icon_url( get_current_blog_id(), 512 ) ); 
  419.  
  420. ?> 
  421. <h2 class="site-icon-title"><?php esc_html_e( 'Site Icon', 'jetpack' ); ?> <span class="small"><?php esc_html_e( 'All Done', 'jetpack' ); ?></span></h2> 
  422. <div id="message" class="updated below-h2"><p><?php esc_html_e( 'Your site icon has been uploaded!', 'jetpack' ); ?> <a href="<?php echo esc_url( admin_url( 'options-general.php' ) ); ?>" ><?php esc_html_e( 'Back to General Settings' , 'jetpack' ); ?></a></p></div> 
  423. <?php echo jetpack_get_site_icon( null, $size = '128' ); ?> 
  424. <?php echo jetpack_get_site_icon( null, $size = '48' ); ?> 
  425. <?php echo jetpack_get_site_icon( null, $size = '16' ); ?> 
  426.  
  427. <?php 
  428.  
  429. /** 
  430. * This function is used to pass data to the localize script 
  431. * so that we can center the cropper and also set the minimum 
  432. * cropper if we still want to show the 
  433. * @param int $large_width 
  434. * @param int $large_height 
  435. * @param int $resized_width 
  436. * @param int $resized_height 
  437. * @return array 
  438. */ 
  439. public static function initial_crop_data( $large_width, $large_height, $resized_width, $resized_height ) { 
  440. $init_x = 0; 
  441. $init_y = 0; 
  442.  
  443. $ration = $large_width / $resized_width; 
  444. $min_crop_size = ( self::$min_size / $ration ); 
  445.  
  446. // Landscape format ( width > height ) 
  447. if( $resized_width > $resized_height ) { 
  448. $init_x = ( self::$page_crop - $resized_height ) / 2; 
  449. $init_size = $resized_height; 
  450.  
  451. // Portrait format ( height > width ) 
  452. if( $resized_width < $resized_height ) { 
  453. $init_y = ( self::$page_crop - $resized_width ) / 2; 
  454. $init_size = $resized_height; 
  455.  
  456. // Square height == width 
  457. if( $resized_width = $resized_height ) { 
  458. $init_size = $resized_height; 
  459.  
  460. return array( 
  461. 'init_x' => $init_x,  
  462. 'init_y' => $init_y,  
  463. 'init_size' => $init_size,  
  464. 'min_size' => $min_crop_size 
  465. ); 
  466.  
  467. /** 
  468. * Delete the temporary created data and attachments 
  469. * @return null 
  470. */ 
  471. public static function delete_temporay_data() { 
  472. // This should autimatically delete the temporary files as well 
  473. delete_option( 'site_icon_temp_data' ); 
  474.  
  475. /** 
  476. * Function gets fired when delete_option( 'site_icon_temp_data' ) is run. 
  477. * @param $option string 
  478. * @return null 
  479. */ 
  480. public static function delete_temp_data( $option ) { 
  481. if( 'site_icon_temp_data' == $option ) { 
  482. $temp_image_data = get_option( 'site_icon_temp_data' ); 
  483.  
  484. remove_action( 'delete_attachment', array( 'Jetpack_Site_Icon', 'delete_attachment_data' ), 10, 1); 
  485.  
  486. wp_delete_attachment( $temp_image_data['large_image_attachment_id'] , true ); 
  487. wp_delete_attachment( $temp_image_data['resized_image_attacment_id'] , true ); 
  488. return null; 
  489.  
  490. /** 
  491. * @param $post_id 
  492. */ 
  493. public static function delete_attachment_data( $post_id ) { 
  494. // The user could be deleting the site_icon image 
  495. $site_icon_id = Jetpack_Options::get_option( 'site_icon_id' ); 
  496. if( $site_icon_id && $post_id == $site_icon_id ) { 
  497. Jetpack_Options::delete_option( 'site_icon_id' ); 
  498. Jetpack_Options::delete_option( 'site_icon_url' ); 
  499. // The user could be deleting the temporary images 
  500.  
  501. /** 
  502. * @param $check 
  503. * @param $post_id 
  504. * @param $meta_key 
  505. * @param $single 
  506. * @return mixed 
  507. */ 
  508. public static function delete_attachment_images( $check, $post_id, $meta_key, $single ) { 
  509. $site_icon_id = Jetpack_Options::get_option( 'site_icon_id' ); 
  510. if( $post_id == $site_icon_id && '_wp_attachment_backup_sizes' == $meta_key && true == $single ) 
  511. add_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) ); 
  512. return $check; 
  513.  
  514. /** 
  515. * Delete the blavatar and all the attached data 
  516. * @param $id 
  517. * @return mixed 
  518. */ 
  519. public static function delete_site_icon( $id ) { 
  520. // We add the filter to make sure that we also delete all the added images 
  521. add_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) ); 
  522. wp_delete_attachment( $id , true ); 
  523. remove_filter( 'intermediate_image_sizes', array( 'Jetpack_Site_Icon', 'intermediate_image_sizes' ) ); 
  524. // for good measure also 
  525. self::delete_temporay_data(); 
  526.  
  527. // Delete the URL from the Jetpack Options array 
  528. Jetpack_Options::delete_option( 'site_icon_url' ); 
  529.  
  530. return Jetpack_Options::delete_option( 'site_icon_id' ); 
  531.  
  532. /** 
  533. * @param $crop_x 
  534. * @param $crop_y 
  535. * @param $crop_width 
  536. * @param $crop_height 
  537. * @param $ratio 
  538. * @return array 
  539. */ 
  540. public static function convert_coodiantes_from_resized_to_full( $crop_x, $crop_y, $crop_width, $crop_height, $ratio ) { 
  541. return array( 
  542. 'crop_x' => floor( $crop_x * $ratio ),  
  543. 'crop_y' => floor( $crop_y * $ratio ),  
  544. 'crop_width' => floor( $crop_width * $ratio ),  
  545. 'crop_height' => floor( $crop_height * $ratio ),  
  546. ); 
  547.  
  548. /** 
  549. * Handle the uploaded image 
  550. * @param $uploaded_file 
  551. * @return mixed 
  552. */ 
  553. public static function handle_file_upload( $uploaded_file ) { 
  554.  
  555. // check that the image accuallt is a file with size 
  556. if( !isset( $uploaded_file ) || ($uploaded_file['size'] <= 0 ) ) { 
  557. return new WP_Error( 'broke', __( 'Please upload a file.', 'jetpack' ) ); 
  558.  
  559. $arr_file_type = wp_check_filetype( basename( $uploaded_file['name'] ) ); 
  560. $uploaded_file_type = $arr_file_type['type']; 
  561. if( ! in_array( $uploaded_file_type, self::$accepted_file_types ) ) { 
  562. // Create a temp file which should be deleted at when the scipt stops 
  563. return new WP_Error( 'broke', __( 'The file that you uploaded is not an accepted file type. Please try again.', 'jetpack' ) ); 
  564.  
  565. $image = wp_handle_upload( $uploaded_file, array( 'test_form' => false ) ); 
  566.  
  567. if( is_wp_error( $image ) ) { 
  568. // this should contain the error message returned from wp_handle_upload 
  569. unlink( $image['file'] ); // Lets delete the file since we are not going to be using it 
  570. return $image; 
  571.  
  572. // Lets try to crop the image into smaller files. 
  573. // We will be doing this later so it is better if it fails now. 
  574. $image_edit = wp_get_image_editor( $image['file'] ); 
  575. if ( is_wp_error( $image_edit ) ) { 
  576. // this should contain the error message from WP_Image_Editor 
  577. unlink( $image['file'] ); // lets delete the file since we are not going to be using it 
  578. return $image_edit; 
  579.  
  580. $image_size = getimagesize( $image['file'] ); 
  581.  
  582. if( $image_size[0] < self::$min_size || $image_size[1] < self::$min_size ) { 
  583.  
  584. if( $image_size[0] < self::$min_size ) { 
  585. return new WP_Error( 'broke', sprintf( __( 'The image that you uploaded is smaller than %upx in width.', 'jetpack' ), self::$min_size ) ); 
  586.  
  587. if( $image_size[1] < self::$min_size ) { 
  588. return new WP_Error( 'broke', sprintf( __( 'The image that you uploaded is smaller than %upx in height.', 'jetpack' ), self::$min_size ) ); 
  589.  
  590. // Save the image as an attachment for later use. 
  591. $large_attachment_id = self::save_attachment( 
  592. __( 'Temporary Large Image for Blog Image', 'jetpack' ) ,  
  593. $image['file'],  
  594. $uploaded_file_type,  
  595. false 
  596. ); 
  597.  
  598. // Let's resize the image so that the user can easier crop a image that in the admin view 
  599. $image_edit->resize( self::$page_crop, self::$page_crop, false ); 
  600. $dir = wp_upload_dir(); 
  601.  
  602. $resized_filename = $image_edit->generate_filename( 'temp', null, null ); 
  603. $image_edit->save( $resized_filename ); 
  604.  
  605. $resized_attach_id = self::save_attachment( 
  606. __( 'Temporary Resized Image for Blog Image', 'jetpack' ),  
  607. $resized_filename,  
  608. $uploaded_file_type,  
  609. false 
  610. ); 
  611.  
  612. $resized_image_size = getimagesize( $resized_filename ); 
  613. // Save all of this into the the database for that we can work with it later. 
  614. update_option( 'site_icon_temp_data', array( 
  615. 'large_image_attachment_id' => $large_attachment_id,  
  616. 'large_image_data' => $image_size,  
  617. 'resized_image_attacment_id' => $resized_attach_id,  
  618. 'resized_image_data' => $resized_image_size 
  619. ) ); 
  620.  
  621. return wp_get_attachment_image_src( $resized_attach_id, 'full' ); 
  622.  
  623. /** 
  624. * Save Blavatar files to Media Library 
  625. * @param string $title 
  626. * @param string $filename 
  627. * @param string $file_type 
  628. * @param boolean $generate_meta 
  629. * @return int $attactment_id 
  630. */ 
  631. public static function save_attachment( $title, $file, $file_type, $generate_meta = true ) { 
  632.  
  633. $filename = _wp_relative_upload_path( $file ); 
  634.  
  635. $wp_upload_dir = wp_upload_dir(); 
  636. $attachment = array( 
  637. 'guid' => $wp_upload_dir['url'] . '/' . basename( $filename ),  
  638. 'post_mime_type' => $file_type,  
  639. 'post_title' => $title,  
  640. 'post_content' => '',  
  641. 'post_status' => 'inherit' 
  642. ); 
  643. $attachment_id = wp_insert_attachment( $attachment, $filename ); 
  644.  
  645. if( ! function_exists( 'wp_generate_attachment_metadata' ) ) { 
  646. // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it. 
  647. require_once( ABSPATH . 'wp-admin/includes/image.php' ); 
  648. if( !$generate_meta ) 
  649. add_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'only_thumbnail_size' ) ); 
  650.  
  651. // Generate the metadata for the attachment, and update the database record. 
  652. $attach_data = wp_generate_attachment_metadata( $attachment_id, $file ); 
  653. wp_update_attachment_metadata( $attachment_id, $attach_data ); 
  654.  
  655. if( !$generate_meta ) { 
  656. remove_filter( 'intermediate_image_sizes_advanced', array( 'Jetpack_Site_Icon', 'only_thumbnail_size' ) ); 
  657.  
  658. return $attachment_id; 
  659.  
  660. /** 
  661. * Add additional sizes to be made when creating the site_icon images 
  662. * @param array $sizes 
  663. * @return array 
  664. */ 
  665. public static function additional_sizes( $sizes ) { 
  666. /** 
  667. * Filter the different dimensions that a site icon is saved in. 
  668. * @module site-icon 
  669. * @since 3.2.0 
  670. * @param array $site_icon_sizes Sizes available for the Site Icon. Default is array(256, 128, 80, 64, 32, 16). 
  671. */ 
  672. self::$site_icon_sizes = apply_filters( 'site_icon_image_sizes', self::$site_icon_sizes ); 
  673. // use a natural sort of numbers 
  674. natsort( self::$site_icon_sizes ); 
  675. self::$site_icon_sizes = array_reverse ( self::$site_icon_sizes ); 
  676.  
  677. // ensure that we only resize the image into 
  678. foreach( $sizes as $name => $size_array ) { 
  679. if( $size_array['crop'] ) { 
  680. $only_crop_sizes[ $name ] = $size_array; 
  681.  
  682. foreach( self::$site_icon_sizes as $size ) { 
  683. if( $size < self::$min_size ) { 
  684.  
  685. $only_crop_sizes['site_icon-'.$size] = array( 
  686. "width" => $size,  
  687. "height"=> $size,  
  688. "crop" => true,  
  689. ); 
  690.  
  691. return $only_crop_sizes; 
  692.  
  693. /** 
  694. * Helps us delete site_icon images that 
  695. * @param [type] $sizes [description] 
  696. * @return array 
  697. */ 
  698. public static function intermediate_image_sizes( $sizes ) { 
  699. /** This filter is documented in modules/site-icon/jetpack-site-icon.php */ 
  700. self::$site_icon_sizes = apply_filters( 'site_icon_image_sizes', self::$site_icon_sizes ); 
  701. foreach( self::$site_icon_sizes as $size ) { 
  702. $sizes[] = 'site_icon-'.$size; 
  703. return $sizes; 
  704. /** 
  705. * Only resize the image to thumbnail so we can use 
  706. * Use when resizing temporary images. This way we can see the temp image in Media Gallery. 
  707. * @param array $sizes 
  708. * @return array 
  709. */ 
  710. public static function only_thumbnail_size( $sizes ) { 
  711. foreach( $sizes as $name => $size_array ) { 
  712. if( 'thumbnail' == $name ) { 
  713. $only_thumb['thumbnail'] = $size_array; 
  714. return $only_thumb;