PluginProbe
HEIC Support / 1.0.1
HEIC Support v1.0.1
2.3.0 2.2.1 trunk 1.0.0 1.0.1 2.0.0 2.1.0 2.1.1 2.1.3 2.1.4 2.2.0
heic-support / heic-support.php

heic-support.php in HEIC Support 1.0.1, at heic-support.php

268 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * HEIC Support
4 *
5 * @package HEIC_Support
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 /**
11 * Plugin Name: HEIC Support
12 * Description: Allows .heic uploads to the Media Library. Creates a .webp copy of .heic images when they are uploaded.
13 * Author: Breakfast Co.
14 * Author URI: https://breakfastco.xyz/
15 * Version: 1.0.1
16 * Text-domain: heic-support
17 * License: GPLv2
18 */
19
20 // CORE FUNCTIONALITY.
21
22 /**
23 * Allow .heic files to be uploaded into the Media Library.
24 *
25 * @param array $mimes Array of allowed mime types.
26 * @param int|WP_User|null $user The current user.
27 * @return array
28 */
29 function heic_support_add_mimes( $mimes, $user ) {
30 if ( empty( $mimes['heic'] ) ) {
31 $mimes['heic'] = 'image/heic';
32 }
33 return $mimes;
34 }
35 add_filter( 'upload_mimes', 'heic_support_add_mimes', 10, 2 );
36
37 /**
38 * Filter callback on add_attachment. Creates a .webp copy of .heic images
39 * uploaded to the Media Library.
40 *
41 * @param int $post_id The ID of a new attachment.
42 * @return void
43 */
44 function heic_support_create_webp_copy( $post_id ) {
45 // Is ImageMagick running?
46 if ( ! class_exists( 'Imagick' ) ) {
47 // No.
48 return;
49 }
50 $file_path = get_attached_file( $post_id );
51 if ( false === $file_path ) {
52 return;
53 }
54 // Is the attachment an heic?
55 if ( 'heic' !== pathinfo( $file_path, PATHINFO_EXTENSION ) ) {
56 // No.
57 return;
58 }
59 $imagick = new Imagick();
60 try {
61 if ( $imagick->readImage( $file_path ) ) {
62 $imagick->setImageFormat( 'webp' );
63 // Create a path to create a webp copy of the image.
64 $name = basename( $file_path, '.heic' ) . '.webp';
65 $upload_dir = wp_upload_dir();
66 $imagick->writeImage( $upload_dir['path'] . DIRECTORY_SEPARATOR . $name );
67
68 /**
69 * The Media Library loads these files, but not the Editor.
70 *
71 * @link https://developer.wordpress.org/reference/functions/media_sideload_image/#more-information
72 */
73 if ( ! function_exists( 'media_sideload_image' ) ) {
74 require_once ABSPATH . 'wp-admin/includes/media.php';
75 require_once ABSPATH . 'wp-admin/includes/file.php';
76 require_once ABSPATH . 'wp-admin/includes/image.php';
77 }
78 $copy_post_id = media_sideload_image( $upload_dir['url'] . '/' . $name, 0, get_the_title( $post_id ), 'id' );
79 if ( ! is_wp_error( $copy_post_id ) ) {
80 update_post_meta( $copy_post_id, '_heic_support_copy_of', $post_id );
81 update_post_meta( $post_id, '_heic_support_copy_of', $copy_post_id );
82 }
83 }
84 } catch ( ImagickException $ie ) {
85 // "Fatal error: Uncaught ImagickException: no decode delegate for this image format `HEIC'".
86 // The version of Imagick does not support heic
87 return;
88 }
89 }
90 add_action( 'add_attachment', 'heic_support_create_webp_copy', 12, 1 );
91
92 /**
93 * When .heic files are added to the Media Library, populate their width,
94 * height, and other attributes that live in meta key _wp_attachment_metadata.
95 *
96 * @param array $metadata An array of attachment meta data.
97 * @param int $attachment_id Current attachment ID.
98 * @param string $context Additional context. Can be 'create' when metadata was initially created for new attachment
99 * or 'update' when the metadata was updated.
100 * @return array
101 */
102 function heic_support_populate_meta( $metadata, $attachment_id, $context ) {
103 // Is ImageMagick running?
104 if ( ! class_exists( 'Imagick' ) ) {
105 // No.
106 return $metadata;
107 }
108 $file_path = get_attached_file( $attachment_id );
109 if ( false === $file_path ) {
110 return $metadata;
111 }
112 // Is the attachment an heic?
113 if ( 'heic' !== pathinfo( $file_path, PATHINFO_EXTENSION ) ) {
114 // No.
115 return $metadata;
116 }
117 // Are the width and height missing?
118 if ( false === $metadata ) {
119 $metadata = array();
120 }
121 if ( ! empty( $metadata['width'] ) && ! empty( $metadata['height'] ) ) {
122 // No.
123 return $metadata;
124 }
125 $imagick = new Imagick();
126 try {
127 if ( $imagick->readImage( $file_path ) ) {
128 $new_values = $imagick->getImageGeometry();
129 $new_values['sizes'] = array();
130 $new_values['file'] = get_post_meta( $attachment_id, '_wp_attached_file', true );
131 $metadata = wp_parse_args( $metadata, $new_values );
132 return $metadata;
133 }
134 } catch ( ImagickException $ie ) {
135 // "Fatal error: Uncaught ImagickException: no decode delegate for this image format `HEIC'".
136 // The version of Imagick does not support heic
137 return $metadata;
138 }
139 }
140 add_filter( 'wp_generate_attachment_metadata', 'heic_support_populate_meta', 10, 3 );
141
142 // SETTINGS PAGE.
143
144 /**
145 * Adds an HEIC Support submenu under Media.
146 *
147 * @return void
148 */
149 function heic_support_add_menu() {
150 add_submenu_page(
151 'upload.php',
152 __( 'HEIC Support', 'heic-support' ),
153 __( 'HEIC Support', 'heic-support' ),
154 'upload_files',
155 'heic-support',
156 'heic_support_page_content'
157 );
158 }
159 add_action( 'admin_menu', 'heic_support_add_menu' );
160
161 /**
162 * Returns the ImageMagick version string.
163 *
164 * @return string
165 */
166 function heic_support_imagemagick_version() {
167 if ( ! class_exists( 'Imagick' ) ) {
168 return '';
169 }
170 return Imagick::getVersion()['versionString'];
171 }
172
173 /**
174 * Outputs HTML that renders the HEIC Support dashboard page.
175 *
176 * @return void
177 */
178 function heic_support_page_content() {
179 ?>
180 <div class="wrap">
181 <h2><?php esc_html_e( 'HEIC Support', 'heic-support' ); ?></h2>
182 <p>
183 <?php
184 esc_html_e( 'This plugin only works on servers running ImageMagick 7 or above. ', 'heic-support' );
185 if ( ! class_exists( 'Imagick' ) ) {
186 esc_html_e( 'ImageMagick is not installed on this server. Some hosts require a switch be flipped before the program is available to a site.', 'heic-support' );
187 echo '</p>';
188 } else {
189 $imagick = new Imagick();
190 try {
191 if ( $imagick->readImage( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'image4.heic' ) ) {
192 $imagick->setImageFormat( 'webp' );
193
194 // Create a webp copy of the image.
195 $path = heic_support_test_file_path();
196 $imagick->writeImage( $path );
197 $upload_dir = wp_upload_dir();
198 $name = basename( $path );
199 printf(
200 '</p><p>%s</p><h3>%s</h3><p>%s <a href="https://caniuse.com/webp">caniuse.com/webp</a></p><img src="%s" width="%d" />',
201 esc_html( heic_support_imagemagick_version() ),
202 esc_html__( 'Sample .heic image converted to .webp', 'heic-support' ),
203 esc_html__( 'This plugin is working and can convert .heic images to .webp. If you do not see an image below, your browser may not support .webp.', 'heic-support' ),
204 esc_attr( $upload_dir['url'] . '/' . $name ),
205 esc_attr( get_option( 'medium_size_w' ) )
206 );
207 }
208 } catch ( ImagickException $ie ) {
209 // "Fatal error: Uncaught ImagickException: no decode delegate for this image format `HEIC'".
210 $msg = 'no decode delegate for this image format `HEIC\'';
211 if ( false !== strpos( $ie->getMessage(), $msg ) ) {
212 esc_html_e( 'ImageMagick is installed, but does not support HEIC. Oldest version with HEIC support is 7.0.8-46. Installed version is ', 'heic-support' );
213 echo esc_html( heic_support_imagemagick_version() );
214 echo '</p>';
215 }
216 }
217 }
218 printf(
219 '<h3>%s</h3><p>%s<br><a href="https://imagemagick.org/">imagemagick.org</a></p><p>%s<br /><a href="https://github.com/csalzano/heic-support">github.com/csalzano/heic-support</p></p></div>',
220 esc_html__( 'Links', 'heic-support' ),
221 esc_html__( 'ImageMagick homepage', 'heic-support' ),
222 esc_html__( 'Plugin homepage', 'heic-support' )
223 );
224 }
225
226 /**
227 * Returns a file path to the webp copy of the test image.
228 *
229 * @return void
230 */
231 function heic_support_test_file_path() {
232 $upload_dir = wp_upload_dir();
233 return $upload_dir['path'] . DIRECTORY_SEPARATOR
234 . 'heic-support-image4.webp';
235 }
236
237 /**
238 * Deletes the test image when the plugin is uninstalled.
239 *
240 * @return void
241 */
242 function heic_support_uninstall() {
243 if ( ! is_multisite() ) {
244 $path = heic_support_test_file_path();
245 if ( file_exists( $path ) ) {
246 unlink( $path );
247 }
248 } else {
249 $sites = get_sites(
250 array(
251 'network' => 1,
252 'limit' => 1000,
253 )
254 );
255 foreach ( $sites as $site ) {
256 switch_to_blog( $site->blog_id );
257
258 $path = heic_support_test_file_path();
259 if ( file_exists( $path ) ) {
260 unlink( $path );
261 }
262
263 restore_current_blog();
264 }
265 }
266 }
267 register_uninstall_hook( __FILE__, 'heic_support_uninstall' );
268