PluginProbe
Plus WebP or AVIF / 5.02
Plus WebP or AVIF v5.02
5.21 5.20 5.12 5.11 trunk 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 2.00 2.01 2.02 2.03 2.04 2.05 All 47 releases
plus-webp / lib / class-pluswebp.php

class-pluswebp.php in Plus WebP or AVIF 5.02, at lib/class-pluswebp.php

549 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plus WebP or AVIF
4 *
5 * @package Plus WebP or AVIF
6 * @subpackage PlusWebp Main function
7 /* Copyright (c) 2019- Katsushi Kawamori (email : dodesyoswift312@gmail.com)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 $pluswebp = new PlusWebp();
23
24 /** ==================================================
25 * Class Main function
26 *
27 * @since 1.00
28 */
29 class PlusWebp {
30
31 /** ==================================================
32 * Dir
33 *
34 * @var $upload_dir DIR.
35 */
36 private $upload_dir;
37
38 /** ==================================================
39 * URL
40 *
41 * @var $upload_url URL.
42 */
43 private $upload_url;
44
45 /** ==================================================
46 * Construct
47 *
48 * @since 1.00
49 */
50 public function __construct() {
51
52 $wp_uploads = wp_upload_dir();
53
54 $upload_dir = wp_normalize_path( $wp_uploads['basedir'] );
55 $upload_url = $wp_uploads['baseurl'];
56 if ( is_ssl() ) {
57 $upload_url = str_replace( 'http:', 'https:', $upload_url );
58 }
59 $this->upload_dir = untrailingslashit( $upload_dir );
60 $this->upload_url = untrailingslashit( $upload_url );
61
62 /* Generate metadata */
63 add_filter( 'wp_generate_attachment_metadata', array( $this, 'generate_webp' ), 10, 2 );
64 /* Original hook */
65 add_filter( 'pluswebp_get_allimages', array( $this, 'get_allimages' ), 10, 2 );
66 add_filter( 'pluswebp_mail_messages', array( $this, 'mail_messages' ), 10, 2 );
67 add_action( 'pluswebp_mail_generate_message', array( $this, 'mail_generate_message' ), 10, 2 );
68
69 /* Raise memory */
70 add_filter( 'pluswebp_memory_limit', array( $this, 'raise_memory_limit' ) );
71 /* webp generation control */
72 add_filter( 'wp_upload_image_mime_transforms', array( $this, 'control_mime_type' ), 10, 2 );
73 }
74
75 /** ==================================================
76 * Webp of AVIF generate
77 *
78 * @param array $metadata metadata.
79 * @param int $attachment_id ID.
80 * @return array $metadata metadata.
81 * @since 1.00
82 */
83 public function generate_webp( $metadata, $attachment_id ) {
84
85 $pluswebp_settings = get_option( 'pluswebp' );
86
87 switch ( $pluswebp_settings['output_mime'] ) {
88 case 'image/webp':
89 $ext = 'webp';
90 break;
91 case 'image/avif':
92 $ext = 'avif';
93 break;
94 default:
95 $ext = 'webp';
96 }
97
98 $mime_type = get_post_mime_type( $attachment_id );
99 if ( in_array( $mime_type, $pluswebp_settings['types'] ) ) {
100 $metadata_webp = $metadata;
101 $file_webp = $this->change_ext( $metadata['file'], $ext, $pluswebp_settings['addext'] );
102 $metadata_webp['file'] = $file_webp;
103 if ( '.' === dirname( $file_webp ) ) {
104 $dir_name_url = '/';
105 $dir_name_path = wp_normalize_path( '/' );
106 } else {
107 $dir_name_url = '/' . dirname( $file_webp ) . '/';
108 $dir_name_path = wp_normalize_path( $dir_name_url );
109 }
110 $url = $this->upload_url . $dir_name_url;
111 $path = $this->upload_dir . $dir_name_path;
112
113 foreach ( (array) $metadata['sizes'] as $key => $value ) {
114 $file_thumb = $value['file'];
115 $file_thumb_webp = $this->change_ext( $file_thumb, $ext, $pluswebp_settings['addext'] );
116 $ret = $this->create_webp( $path . $file_thumb, $mime_type, $path . $file_thumb_webp, $pluswebp_settings['quality'], $pluswebp_settings['output_mime'] );
117 if ( $ret ) {
118 $metadata_webp['sizes'][ $key ]['file'] = $file_thumb_webp;
119 $metadata_webp['sizes'][ $key ]['mime-type'] = $pluswebp_settings['output_mime'];
120 $webp_size = filesize( $path . wp_basename( $file_thumb_webp ) );
121 $metadata_webp['sizes'][ $key ]['filesize'] = $webp_size;
122 if ( $pluswebp_settings['replace'] ) {
123 wp_delete_file( $path . $file_thumb );
124 $this->change_db( $url . $file_thumb, $url . $file_thumb_webp );
125 }
126 }
127 }
128
129 $org_img_file = null;
130 if ( array_key_exists( 'original_image', $metadata ) && ! empty( $metadata['original_image'] ) ) {
131 $org_img_file = wp_normalize_path( wp_get_original_image_path( $attachment_id, false ) );
132 $org_webp_file = $this->change_ext( $org_img_file, $ext, $pluswebp_settings['addext'] );
133 $ret = $this->create_webp( $org_img_file, $mime_type, $org_webp_file, $pluswebp_settings['quality'], $pluswebp_settings['output_mime'] );
134 if ( $ret ) {
135 $metadata_webp['original_image'] = wp_basename( $org_webp_file );
136 }
137 }
138
139 $ret = $this->create_webp( $this->upload_dir . '/' . $metadata['file'], $mime_type, $path . wp_basename( $file_webp ), $pluswebp_settings['quality'], $pluswebp_settings['output_mime'] );
140 $webp_size = filesize( $path . wp_basename( $file_webp ) );
141 $metadata_webp['filesize'] = $webp_size;
142 if ( $ret ) {
143 if ( $pluswebp_settings['replace'] ) {
144 $up_post = array(
145 'ID' => $attachment_id,
146 'guid' => $this->upload_url . '/' . $file_webp,
147 'post_mime_type' => $pluswebp_settings['output_mime'],
148 );
149 wp_update_post( $up_post );
150 update_post_meta( $attachment_id, '_wp_attached_file', $file_webp );
151 /* for bulk generate */
152 update_post_meta( $attachment_id, '_wp_attachment_metadata', $metadata_webp );
153 /* delete org file */
154 wp_delete_file( $this->upload_dir . '/' . $metadata['file'] );
155 if ( $org_img_file ) {
156 wp_delete_file( $org_img_file );
157 }
158 /* Replace */
159 $this->change_db( $this->upload_url . '/' . $metadata['file'], $this->upload_url . '/' . $file_webp );
160 /* for hook */
161 $metadata = $metadata_webp;
162 /* for mail */
163 $attach_id = $attachment_id;
164 } else {
165 $post = get_post( $attachment_id );
166 $title = $post->post_title;
167 $attachment = array(
168 'guid' => $this->upload_url . '/' . $file_webp,
169 'post_mime_type' => $pluswebp_settings['output_mime'],
170 'post_title' => $title,
171 'post_content' => '',
172 'post_status' => 'inherit',
173 );
174 $file = $this->upload_dir . '/' . $file_webp;
175 $attach_id = wp_insert_attachment( $attachment, $file );
176
177 /* for XAMPP [ get_attached_file( $attach_id ): Unable to get correct value ] */
178 $metapath_name = str_replace( $this->upload_dir . '/', '', $file );
179 update_post_meta( $attach_id, '_wp_attached_file', $metapath_name );
180
181 wp_update_attachment_metadata( $attach_id, $metadata_webp );
182
183 $author = get_userdata( $post->post_author );
184 $userid = $author->ID;
185 $postdate = get_the_date( 'Y-m-d H:i:s', $attachment_id );
186 $postdategmt = get_gmt_from_date( $postdate );
187 $up_post = array(
188 'ID' => $attach_id,
189 'post_author' => $userid,
190 'post_date' => $postdate,
191 'post_date_gmt' => $postdategmt,
192 'post_modified' => $postdate,
193 'post_modified_gmt' => $postdategmt,
194 );
195 wp_update_post( $up_post );
196 }
197
198 update_option( 'pluswebp_generate', $attach_id );
199
200 /* for Media Library folders term by Organize Media Folder */
201 do_action( 'omf_folders_term_update', $metadata_webp, $attach_id );
202
203 /* for Term filter update by Organize Media Folder */
204 do_action( 'omf_term_filter_update' );
205
206 }
207 }
208
209 return $metadata;
210 }
211
212 /** ==================================================
213 * Thumbnail urls
214 *
215 * @param int $attach_id attach_id.
216 * @param array $metadata metadata.
217 * @param string $upload_url upload_url.
218 * @return array $image_thumbnail(string), $imagethumburls(array)
219 * @since 2.00
220 */
221 private function thumbnail_urls( $attach_id, $metadata, $upload_url ) {
222
223 $image_attr_thumbnail = wp_get_attachment_image_src( $attach_id, 'thumbnail', true );
224 $image_thumbnail = $image_attr_thumbnail[0];
225
226 $imagethumburls = array();
227 if ( ! empty( $metadata ) && array_key_exists( 'sizes', $metadata ) ) {
228 $thumbnails = $metadata['sizes'];
229 $path_file = get_post_meta( $attach_id, '_wp_attached_file', true );
230 $filename = wp_basename( $path_file );
231 $media_path = str_replace( $filename, '', $path_file );
232 $media_url = $upload_url . '/' . $media_path;
233 foreach ( $thumbnails as $key => $key2 ) {
234 $imagethumburls[ $key ] = $media_url . $key2['file'];
235 }
236 }
237
238 return array( $image_thumbnail, $imagethumburls );
239 }
240
241 /** ==================================================
242 * Output datas
243 *
244 * @param int $attach_id attach_id.
245 * @param array $metadata metadata.
246 * @return array (string) $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type(string), $stamptime, $file_size
247 * @since 2.00
248 */
249 private function output_datas( $attach_id, $metadata ) {
250
251 $attachment_link = get_attachment_link( $attach_id );
252 $attachment_url = wp_get_attachment_url( $attach_id );
253 $filename = wp_basename( $attachment_url );
254 if ( ! empty( $metadata ) && array_key_exists( 'original_image', $metadata ) && ! empty( $metadata['original_image'] ) ) {
255 $original_image_url = wp_get_original_image_url( $attach_id );
256 $original_filename = wp_basename( $original_image_url );
257 } else {
258 $original_image_url = null;
259 $original_filename = null;
260 }
261 $mime_type = get_post_mime_type( $attach_id );
262
263 $stamptime = get_the_time( 'Y-n-j ', $attach_id ) . get_the_time( 'G:i:s', $attach_id );
264 if ( ! empty( $metadata ) && array_key_exists( 'filesize', $metadata ) && ! empty( $metadata['filesize'] ) ) {
265 $file_size = $metadata['filesize'];
266 } else {
267 $file_size = @filesize( get_attached_file( $attach_id ) );
268 }
269 if ( ! $file_size ) {
270 $file_size = __( 'Could not retrieve.', 'plus-webp' );
271 } else {
272 $file_size = size_format( $file_size );
273 }
274
275 return array( $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type, $stamptime, $file_size );
276 }
277
278 /** ==================================================
279 * Get All Images
280 *
281 * @param array $types mime types.
282 * @param string $output_mime output mime type.
283 * @since 2.00
284 */
285 public function get_allimages( $types, $output_mime ) {
286
287 if ( empty( $types ) ) {
288 return array( array(), array() );
289 }
290
291 $args = array(
292 'post_type' => 'attachment',
293 'post_status' => 'inherit',
294 'post_mime_type' => $types,
295 'posts_per_page' => -1,
296 'orderby' => 'date',
297 'order' => 'DESC',
298 );
299 $posts = get_posts( $args );
300
301 global $wpdb;
302 $webp_titles = $wpdb->get_col(
303 $wpdb->prepare(
304 "
305 SELECT post_title
306 FROM {$wpdb->prefix}posts
307 WHERE post_type = 'attachment'
308 AND post_mime_type IN ( %s )
309 AND post_status = 'inherit'
310 ",
311 $output_mime,
312 )
313 );
314
315 $post_ids = array();
316 $no_file_ids = array();
317 $count = 0;
318 foreach ( $posts as $post ) {
319 if ( ! in_array( $post->post_title, $webp_titles ) ) {
320 if ( file_exists( get_attached_file( $post->ID ) ) ) {
321 $post_ids[] = $post->ID;
322 } else {
323 $no_file_ids[] = $post->ID;
324 }
325 }
326 }
327
328 return array( $post_ids, $no_file_ids );
329 }
330
331 /** ==================================================
332 * Mail messages hook
333 *
334 * @param array $messages messages.
335 * @param int $webp_id webp ID or avif ID.
336 *
337 * @since 4.00
338 */
339 public function mail_messages( $messages, $webp_id ) {
340
341 $metadata = wp_get_attachment_metadata( $webp_id );
342
343 $message = null;
344 if ( $metadata ) {
345 /* Thumbnail urls */
346 list( $image_thumbnail, $imagethumburls ) = $this->thumbnail_urls( $webp_id, $metadata, $this->upload_url );
347 /* Output datas*/
348 list( $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type, $stamptime, $file_size ) = $this->output_datas( $webp_id, $metadata );
349
350 $message = 'ID: ' . $webp_id . "\n";
351 $message .= __( 'Title', 'plus-webp' ) . ': ' . get_the_title( $webp_id ) . "\n";
352 $message .= __( 'Permalink:', 'plus-webp' ) . ' ' . $attachment_link . "\n";
353 $message .= 'URL: ' . $attachment_url . "\n";
354 $message .= __( 'File name:', 'plus-webp' ) . ' ' . $filename . "\n";
355 if ( ! empty( $original_image_url ) ) {
356 $message .= __( 'Original URL:', 'plus-webp' ) . ' ' . $original_image_url . "\n";
357 $message .= __( 'Original File name:', 'plus-webp' ) . ' ' . $original_filename . "\n";
358 }
359 $message .= __( 'Date/Time', 'plus-webp' ) . ': ' . $stamptime . "\n";
360 $message .= __( 'File size:', 'plus-webp' ) . ' ' . $file_size . "\n";
361 if ( ! empty( $imagethumburls ) ) {
362 foreach ( $imagethumburls as $thumbsize => $imagethumburl ) {
363 $message .= $thumbsize . ': ' . $imagethumburl . "\n";
364 }
365 }
366 $message .= "\n";
367 $messages[] = $message;
368 }
369
370 return array( $message, $messages );
371 }
372
373 /** ==================================================
374 * Mail sent for Generate Messages
375 *
376 * @param array $messages mail messages.
377 * @param int $count convert count.
378 * @since 4.02
379 */
380 public function mail_generate_message( $messages, $count ) {
381
382 if ( function_exists( 'wp_date' ) ) {
383 $now_date_time = wp_date( 'Y-m-d H:i:s' );
384 } else {
385 $now_date_time = date_i18n( 'Y-m-d H:i:s' );
386 }
387 /* translators: Date and Time */
388 $message_head = sprintf( __( 'Plus WebP or AVIF : %s', 'plus-webp' ), $now_date_time ) . "\r\n\r\n";
389 /* translators: Generated count */
390 $message_head .= sprintf( __( 'Webp or AVIF generated %d.', 'plus-webp' ), $count ) . "\r\n\r\n";
391
392 $to = get_option( 'admin_email' );
393 /* translators: blogname for subject */
394 $subject = sprintf( __( '[%s] WebP or AVIF generate', 'plus-webp' ), get_option( 'blogname' ) );
395 wp_mail( $to, $subject, $message_head . implode( $messages ) );
396 }
397
398 /** ==================================================
399 * WebP or AVIF create
400 *
401 * @param string $filename input filename for pictures.
402 * @param string $mime_type mimetype.
403 * @param string $filename_webp output filename for webp or avif.
404 * @param int $quality quality of webp.
405 * @param string $output_mime output mime type.
406 * @return bool $ret create bool.
407 * @since 1.00
408 */
409 private function create_webp( $filename, $mime_type, $filename_webp, $quality, $output_mime ) {
410
411 if ( ! file_exists( $filename ) ) {
412 return false;
413 }
414 if ( file_exists( $filename_webp ) ) {
415 return false;
416 }
417
418 @set_time_limit( 60 );
419 wp_raise_memory_limit( 'pluswebp' );
420
421 $ret = false;
422 switch ( $mime_type ) {
423 case 'image/jpeg':
424 $src = imagecreatefromjpeg( $filename );
425 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
426 $bgcolor = imagecolorallocate( $img, 255, 255, 255 );
427 imagefill( $img, 0, 0, $bgcolor );
428 imagealphablending( $img, true );
429 break;
430 case 'image/png':
431 $src = imagecreatefrompng( $filename );
432 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
433 imagealphablending( $img, false );
434 imagesavealpha( $img, true );
435 $bgcolor = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
436 imagefill( $img, 0, 0, $bgcolor );
437 imagecolortransparent( $img, $bgcolor );
438 break;
439 case 'image/bmp':
440 $src = imagecreatefrombmp( $filename );
441 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
442 break;
443 case 'image/gif':
444 $src = imagecreatefromgif( $filename );
445 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
446 $bgcolor = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
447 imagefill( $img, 0, 0, $bgcolor );
448 imagecolortransparent( $img, $bgcolor );
449 break;
450 }
451
452 imagecopy( $img, $src, 0, 0, 0, 0, imagesx( $src ), imagesy( $src ) );
453 imagedestroy( $src );
454
455 switch ( $output_mime ) {
456 case 'image/webp':
457 $ret = imagewebp( $img, $filename_webp, $quality );
458 break;
459 case 'image/avif':
460 $ret = imageavif( $img, $filename_webp, $quality );
461 break;
462 default:
463 $ret = imagewebp( $img, $filename_webp, $quality );
464 }
465
466 imagedestroy( $img );
467
468 return $ret;
469 }
470
471 /** ==================================================
472 * Change ext
473 *
474 * @param string $before_file_name before_file_name.
475 * @param string $ext ext.
476 * @param bool $addext addext.
477 * @return array $after_file_name after_file_name.
478 * @since 1.00
479 */
480 private function change_ext( $before_file_name, $ext, $addext ) {
481
482 if ( $addext ) {
483 $after_file_name = $before_file_name . '.' . $ext;
484 } else {
485 $exts = explode( '.', $before_file_name );
486 $before_ext = '.' . end( $exts );
487 $after_ext = '.' . $ext;
488 $after_file_name = str_replace( $before_ext, $after_ext, $before_file_name );
489 }
490
491 return $after_file_name;
492 }
493
494 /** ==================================================
495 * Change DB
496 *
497 * @param string $before_url before_url.
498 * @param string $after_url after_url.
499 * @since 1.00
500 */
501 private function change_db( $before_url, $after_url ) {
502
503 global $wpdb;
504
505 /* Replace */
506 $wpdb->query(
507 $wpdb->prepare(
508 "
509 UPDATE {$wpdb->prefix}posts
510 SET post_content = replace( post_content, %s, %s )
511 ",
512 $before_url,
513 $after_url
514 )
515 );
516
517 /* Advanced change database */
518 list( $before_url, $after_url ) = apply_filters( 'plus_webp_advanced_change_db', $before_url, $after_url );
519 }
520
521 /** ==================================================
522 * Filter Raise Memory limit
523 *
524 * @since 3.00
525 *
526 * @param string $filtered_limit Memory limit.
527 */
528 public function raise_memory_limit( $filtered_limit ) {
529
530 return '256M';
531 }
532
533 /** ==================================================
534 * Filter the output mime types for a given input mime type and image size.
535 *
536 * @since 3.00
537 *
538 * @param array $image_mime_transforms A map with the valid mime transforms where the key is the source file mime type
539 * and the value is one or more mime file types to generate.
540 * @param int $attachment_id The ID of the attachment where the hook was dispatched.
541 */
542 public function control_mime_type( $image_mime_transforms, $attachment_id ) {
543
544 $image_mime_transforms = array();
545
546 return $image_mime_transforms;
547 }
548 }
549