PluginProbe
Plus WebP or AVIF / 4.03
Plus WebP or AVIF v4.03
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 4.03, at lib/class-pluswebp.php

542 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plus WebP
4 *
5 * @package Plus WebP
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 * Path
47 *
48 * @var $upload_path PATH.
49 */
50 private $upload_path;
51
52 /** ==================================================
53 * Construct
54 *
55 * @since 1.00
56 */
57 public function __construct() {
58
59 list( $this->upload_dir, $this->upload_url, $this->upload_path ) = $this->upload_dir_url_path();
60
61 /* Generate metadata */
62 add_filter( 'wp_generate_attachment_metadata', array( $this, 'generate_webp' ), 10, 2 );
63 /* Original hook */
64 add_filter( 'pluswebp_mail_messages', array( $this, 'mail_messages' ), 10, 2 );
65
66 /* Raise memory */
67 add_filter( 'pluswebp_memory_limit', array( $this, 'raise_memory_limit' ) );
68 /* webp generation control */
69 add_filter( 'wp_upload_image_mime_transforms', array( $this, 'control_mime_type' ), 10, 2 );
70
71 }
72
73 /** ==================================================
74 * Webp generate
75 *
76 * @param array $metadata metadata.
77 * @param int $attachment_id ID.
78 * @return array $metadata metadata.
79 * @since 1.00
80 */
81 public function generate_webp( $metadata, $attachment_id ) {
82
83 $pluswebp_settings = get_option( 'pluswebp' );
84 $replace = $pluswebp_settings['replace'];
85
86 $mime_type = get_post_mime_type( $attachment_id );
87 if ( in_array( $mime_type, $pluswebp_settings['types'] ) ) {
88 $metadata_webp = $metadata;
89 $file_webp = $this->change_ext( $metadata['file'], 'webp', $pluswebp_settings['addext'] );
90 $metadata_webp['file'] = $file_webp;
91 if ( '.' === dirname( $file_webp ) ) {
92 $dir_name_url = '/';
93 $dir_name_path = wp_normalize_path( '/' );
94 } else {
95 $dir_name_url = '/' . dirname( $file_webp ) . '/';
96 $dir_name_path = wp_normalize_path( $dir_name_url );
97 }
98 $url = $this->upload_url . $dir_name_url;
99 $path = $this->upload_dir . $dir_name_path;
100
101 foreach ( (array) $metadata['sizes'] as $key => $value ) {
102 $file_thumb = $value['file'];
103 $file_thumb_webp = $this->change_ext( $file_thumb, 'webp', $pluswebp_settings['addext'] );
104 $ret = $this->create_webp( $path . $file_thumb, $mime_type, $path . $file_thumb_webp );
105 if ( $ret ) {
106 $metadata_webp['sizes'][ $key ]['file'] = $file_thumb_webp;
107 $metadata_webp['sizes'][ $key ]['mime-type'] = 'image/webp';
108 $webp_size = filesize( $path . wp_basename( $file_thumb_webp ) );
109 $metadata_webp['sizes'][ $key ]['filesize'] = $webp_size;
110 if ( $replace ) {
111 unlink( $path . $file_thumb );
112 $this->change_db( $url . $file_thumb, $url . $file_thumb_webp );
113 }
114 }
115 }
116
117 $org_img_file = null;
118 if ( array_key_exists( 'original_image', $metadata ) && ! empty( $metadata['original_image'] ) ) {
119 $org_img_file = wp_normalize_path( wp_get_original_image_path( $attachment_id, false ) );
120 $org_webp_file = $this->change_ext( $org_img_file, 'webp', $pluswebp_settings['addext'] );
121 $ret = $this->create_webp( $org_img_file, $mime_type, $org_webp_file );
122 if ( $ret ) {
123 $metadata_webp['original_image'] = wp_basename( $org_webp_file );
124 }
125 }
126
127 $ret = $this->create_webp( $this->upload_dir . '/' . $metadata['file'], $mime_type, $path . wp_basename( $file_webp ) );
128 $webp_size = filesize( $path . wp_basename( $file_webp ) );
129 $metadata_webp['filesize'] = $webp_size;
130 if ( $ret ) {
131 if ( $replace ) {
132 $up_post = array(
133 'ID' => $attachment_id,
134 'guid' => $this->upload_url . '/' . $file_webp,
135 'post_mime_type' => 'image/webp',
136 );
137 wp_update_post( $up_post );
138 update_post_meta( $attachment_id, '_wp_attached_file', $file_webp );
139 /* for bulk generate */
140 update_post_meta( $attachment_id, '_wp_attachment_metadata', $metadata_webp );
141 /* delete org file */
142 unlink( $this->upload_dir . '/' . $metadata['file'] );
143 if ( $org_img_file ) {
144 unlink( $org_img_file );
145 }
146 /* Replace */
147 $this->change_db( $this->upload_url . '/' . $metadata['file'], $this->upload_url . '/' . $file_webp );
148 /* for hook */
149 $metadata = $metadata_webp;
150 /* for mail */
151 $attach_id = $attachment_id;
152 } else {
153 $post = get_post( $attachment_id );
154 $title = $post->post_title;
155 $attachment = array(
156 'guid' => $this->upload_url . '/' . $file_webp,
157 'post_mime_type' => 'image/webp',
158 'post_title' => $title,
159 'post_content' => '',
160 'post_status' => 'inherit',
161 );
162 $file = $this->upload_dir . '/' . $file_webp;
163 $attach_id = wp_insert_attachment( $attachment, $file );
164
165 /* for XAMPP [ get_attached_file( $attach_id ): Unable to get correct value ] */
166 $metapath_name = str_replace( $this->upload_dir . '/', '', $file );
167 update_post_meta( $attach_id, '_wp_attached_file', $metapath_name );
168
169 wp_update_attachment_metadata( $attach_id, $metadata_webp );
170
171 $author = get_userdata( $post->post_author );
172 $userid = $author->ID;
173 $postdate = get_the_date( 'Y-m-d H:i:s', $attachment_id );
174 $postdategmt = get_gmt_from_date( $postdate );
175 $up_post = array(
176 'ID' => $attach_id,
177 'post_author' => $userid,
178 'post_date' => $postdate,
179 'post_date_gmt' => $postdategmt,
180 'post_modified' => $postdate,
181 'post_modified_gmt' => $postdategmt,
182 );
183 wp_update_post( $up_post );
184 }
185
186 update_option( 'pluswebp_generate', $attach_id );
187
188 /* for Media Library folders term by Organize Media Folder */
189 do_action( 'omf_folders_term_update', $metadata_webp, $attach_id );
190
191 /* for Term filter update by Organize Media Folder */
192 do_action( 'omf_term_filter_update' );
193
194 }
195 }
196
197 return $metadata;
198
199 }
200
201 /** ==================================================
202 * Thumbnail urls
203 *
204 * @param int $attach_id attach_id.
205 * @param array $metadata metadata.
206 * @param string $upload_url upload_url.
207 * @return array $image_thumbnail(string), $imagethumburls(array)
208 * @since 2.00
209 */
210 private function thumbnail_urls( $attach_id, $metadata, $upload_url ) {
211
212 $image_attr_thumbnail = wp_get_attachment_image_src( $attach_id, 'thumbnail', true );
213 $image_thumbnail = $image_attr_thumbnail[0];
214
215 $imagethumburls = array();
216 if ( ! empty( $metadata ) && array_key_exists( 'sizes', $metadata ) ) {
217 $thumbnails = $metadata['sizes'];
218 $path_file = get_post_meta( $attach_id, '_wp_attached_file', true );
219 $filename = wp_basename( $path_file );
220 $media_path = str_replace( $filename, '', $path_file );
221 $media_url = $upload_url . '/' . $media_path;
222 foreach ( $thumbnails as $key => $key2 ) {
223 $imagethumburls[ $key ] = $media_url . $key2['file'];
224 }
225 }
226
227 return array( $image_thumbnail, $imagethumburls );
228
229 }
230
231 /** ==================================================
232 * Output datas
233 *
234 * @param int $attach_id attach_id.
235 * @param array $metadata metadata.
236 * @return array (string) $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type(string), $stamptime, $file_size
237 * @since 2.00
238 */
239 private function output_datas( $attach_id, $metadata ) {
240
241 $attachment_link = get_attachment_link( $attach_id );
242 $attachment_url = wp_get_attachment_url( $attach_id );
243 $filename = wp_basename( $attachment_url );
244 if ( ! empty( $metadata ) && array_key_exists( 'original_image', $metadata ) && ! empty( $metadata['original_image'] ) ) {
245 $original_image_url = wp_get_original_image_url( $attach_id );
246 $original_filename = wp_basename( $original_image_url );
247 } else {
248 $original_image_url = null;
249 $original_filename = null;
250 }
251 $mime_type = get_post_mime_type( $attach_id );
252
253 $stamptime = get_the_time( 'Y-n-j ', $attach_id ) . get_the_time( 'G:i:s', $attach_id );
254 if ( ! empty( $metadata ) && array_key_exists( 'filesize', $metadata ) && ! empty( $metadata['filesize'] ) ) {
255 $file_size = $metadata['filesize'];
256 } else {
257 $file_size = @filesize( get_attached_file( $attach_id ) );
258 }
259 if ( ! $file_size ) {
260 $file_size = __( 'Could not retrieve.', 'plus-webp' );
261 } else {
262 $file_size = size_format( $file_size );
263 }
264
265 return array( $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type, $stamptime, $file_size );
266
267 }
268
269 /** ==================================================
270 * Mail messages hook
271 *
272 * @param array $messages messages.
273 * @param int $webp_id webp_id.
274 *
275 * @since 4.00
276 */
277 public function mail_messages( $messages, $webp_id ) {
278
279 $metadata = wp_get_attachment_metadata( $webp_id );
280
281 if ( $metadata ) {
282 /* Thumbnail urls */
283 list( $image_thumbnail, $imagethumburls ) = $this->thumbnail_urls( $webp_id, $metadata, $this->upload_url );
284 /* Output datas*/
285 list( $attachment_link, $attachment_url, $filename, $original_image_url, $original_filename, $mime_type, $stamptime, $file_size ) = $this->output_datas( $webp_id, $metadata );
286
287 $message = 'ID: ' . $webp_id . "\n";
288 $message .= __( 'Title' ) . ': ' . get_the_title( $webp_id ) . "\n";
289 $message .= __( 'Permalink:' ) . ' ' . $attachment_link . "\n";
290 $message .= 'URL: ' . $attachment_url . "\n";
291 $message .= __( 'File name:' ) . ' ' . $filename . "\n";
292 if ( ! empty( $original_image_url ) ) {
293 $message .= __( 'Original URL:', 'plus-webp' ) . ' ' . $original_image_url . "\n";
294 $message .= __( 'Original File name:', 'plus-webp' ) . ' ' . $original_filename . "\n";
295 }
296 $message .= __( 'Date/Time' ) . ': ' . $stamptime . "\n";
297 $message .= __( 'File size:' ) . ' ' . $file_size . "\n";
298 if ( ! empty( $imagethumburls ) ) {
299 foreach ( $imagethumburls as $thumbsize => $imagethumburl ) {
300 $message .= $thumbsize . ': ' . $imagethumburl . "\n";
301 }
302 }
303 $message .= "\n";
304 $messages[] = $message;
305 }
306
307 return $messages;
308
309 }
310
311 /** ==================================================
312 * Webp create
313 *
314 * @param string $filename input filename for pictures.
315 * @param string $mime_type mimetype.
316 * @param string $filename_webp output filename for webp.
317 * @return bool $ret create bool.
318 * @since 1.00
319 */
320 private function create_webp( $filename, $mime_type, $filename_webp ) {
321
322 if ( ! file_exists( $filename ) ) {
323 return false;
324 }
325 if ( file_exists( $filename_webp ) ) {
326 return false;
327 }
328
329 $pluswebp_settings = get_option( 'pluswebp' );
330 @set_time_limit( 60 );
331 wp_raise_memory_limit( 'pluswebp' );
332
333 $ret = false;
334 switch ( $mime_type ) {
335 case 'image/jpeg':
336 $src = imagecreatefromjpeg( $filename );
337 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
338 $bgcolor = imagecolorallocate( $img, 255, 255, 255 );
339 imagefill( $img, 0, 0, $bgcolor );
340 imagealphablending( $img, true );
341 break;
342 case 'image/png':
343 $src = imagecreatefrompng( $filename );
344 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
345 imagealphablending( $img, false );
346 imagesavealpha( $img, true );
347 break;
348 case 'image/bmp':
349 $src = imagecreatefrombmp( $filename );
350 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
351 break;
352 case 'image/gif':
353 $src = imagecreatefromgif( $filename );
354 $img = imagecreatetruecolor( imagesx( $src ), imagesy( $src ) );
355 $bgcolor = imagecolorallocatealpha( $img, 0, 0, 0, 127 );
356 imagefill( $img, 0, 0, $bgcolor );
357 imagecolortransparent( $img, $bgcolor );
358 break;
359 }
360
361 imagecopy( $img, $src, 0, 0, 0, 0, imagesx( $src ), imagesy( $src ) );
362 imagedestroy( $src );
363 $ret = imagewebp( $img, $filename_webp, $pluswebp_settings['quality'] );
364 imagedestroy( $img );
365
366 return $ret;
367
368 }
369
370 /** ==================================================
371 * Change ext
372 *
373 * @param string $before_file_name before_file_name.
374 * @param string $ext ext.
375 * @param bool $addext addext.
376 * @return array $after_file_name after_file_name.
377 * @since 1.00
378 */
379 private function change_ext( $before_file_name, $ext, $addext ) {
380
381 if ( $addext ) {
382 $after_file_name = $before_file_name . '.' . $ext;
383 } else {
384 $exts = explode( '.', $before_file_name );
385 $before_ext = '.' . end( $exts );
386 $after_ext = '.' . $ext;
387 $after_file_name = str_replace( $before_ext, $after_ext, $before_file_name );
388 }
389
390 return $after_file_name;
391
392 }
393
394 /** ==================================================
395 * Change DB
396 *
397 * @param string $before_url before_url.
398 * @param string $after_url after_url.
399 * @since 1.00
400 */
401 private function change_db( $before_url, $after_url ) {
402
403 global $wpdb;
404
405 /* Replace */
406 $wpdb->query(
407 $wpdb->prepare(
408 "
409 UPDATE {$wpdb->prefix}posts
410 SET post_content = replace( post_content, %s, %s )
411 ",
412 $before_url,
413 $after_url
414 )
415 );
416
417 }
418
419 /** ==================================================
420 * Upload Path
421 *
422 * @return array $upload_dir,$upload_url,$upload_path uploadpath.
423 * @since 1.00
424 */
425 public function upload_dir_url_path() {
426
427 $wp_uploads = wp_upload_dir();
428
429 $relation_path_true = strpos( $wp_uploads['baseurl'], '../' );
430 if ( $relation_path_true > 0 ) {
431 $relationalpath = substr( $wp_uploads['baseurl'], $relation_path_true );
432 $basepath = substr( $wp_uploads['baseurl'], 0, $relation_path_true );
433 $upload_url = $this->realurl( $basepath, $relationalpath );
434 $upload_dir = wp_normalize_path( realpath( $wp_uploads['basedir'] ) );
435 } else {
436 $upload_url = $wp_uploads['baseurl'];
437 $upload_dir = wp_normalize_path( $wp_uploads['basedir'] );
438 }
439
440 if ( is_ssl() ) {
441 $upload_url = str_replace( 'http:', 'https:', $upload_url );
442 }
443
444 if ( $relation_path_true > 0 ) {
445 $upload_path = $relationalpath;
446 } else {
447 $upload_path = str_replace( site_url( '/' ), '', $upload_url );
448 }
449
450 $upload_dir = untrailingslashit( $upload_dir );
451 $upload_url = untrailingslashit( $upload_url );
452 $upload_path = untrailingslashit( $upload_path );
453
454 return array( $upload_dir, $upload_url, $upload_path );
455
456 }
457
458 /** ==================================================
459 * Real Url
460 *
461 * @param string $base base.
462 * @param string $relationalpath relationalpath.
463 * @return string $realurl realurl.
464 * @since 1.00
465 */
466 private function realurl( $base, $relationalpath ) {
467
468 $parse = array(
469 'scheme' => null,
470 'user' => null,
471 'pass' => null,
472 'host' => null,
473 'port' => null,
474 'query' => null,
475 'fragment' => null,
476 );
477 $parse = wp_parse_url( $base );
478
479 if ( strpos( $parse['path'], '/', ( strlen( $parse['path'] ) - 1 ) ) !== false ) {
480 $parse['path'] .= '.';
481 }
482
483 if ( preg_match( '#^https?://#', $relationalpath ) ) {
484 return $relationalpath;
485 } elseif ( preg_match( '#^/.*$#', $relationalpath ) ) {
486 return $parse['scheme'] . '://' . $parse['host'] . $relationalpath;
487 } else {
488 $base_path = explode( '/', dirname( $parse['path'] ) );
489 $rel_path = explode( '/', $relationalpath );
490 foreach ( $rel_path as $rel_dir_name ) {
491 if ( '.' === $rel_dir_name ) {
492 array_shift( $base_path );
493 array_unshift( $base_path, '' );
494 } elseif ( '..' === $rel_dir_name ) {
495 array_pop( $base_path );
496 if ( count( $base_path ) === 0 ) {
497 $base_path = array( '' );
498 }
499 } else {
500 array_push( $base_path, $rel_dir_name );
501 }
502 }
503 $path = implode( '/', $base_path );
504 return $parse['scheme'] . '://' . $parse['host'] . $path;
505 }
506
507 }
508
509 /** ==================================================
510 * Filter Raise Memory limit
511 *
512 * @since 3.00
513 *
514 * @param string $filtered_limit Memory limit.
515 */
516 public function raise_memory_limit( $filtered_limit ) {
517
518 return '256M';
519
520 }
521
522 /** ==================================================
523 * Filter the output mime types for a given input mime type and image size.
524 *
525 * @since 3.00
526 *
527 * @param array $image_mime_transforms A map with the valid mime transforms where the key is the source file mime type
528 * and the value is one or more mime file types to generate.
529 * @param int $attachment_id The ID of the attachment where the hook was dispatched.
530 */
531 public function control_mime_type( $image_mime_transforms, $attachment_id ) {
532
533 $image_mime_transforms = array();
534
535 return $image_mime_transforms;
536
537 }
538
539 }
540
541
542