[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Core attachment class. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 2.3.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * BP Attachment class. 15 * 16 * Extend it to manage your component's uploads. 17 * 18 * @since 2.3.0 19 */ 20 abstract class BP_Attachment { 21 22 /** Upload properties *****************************************************/ 23 24 /** 25 * The file being uploaded. 26 * 27 * @var array 28 */ 29 public $attachment = array(); 30 31 /** 32 * The default args to be merged with the 33 * ones passed by the child class. 34 * 35 * @var array 36 */ 37 protected $default_args = array( 38 'original_max_filesize' => 0, 39 'allowed_mime_types' => array(), 40 'base_dir' => '', 41 'action' => '', 42 'file_input' => '', 43 'upload_error_strings' => array(), 44 'required_wp_files' => array( 'file' ), 45 'upload_dir_filter_args' => 0, 46 ); 47 48 /** 49 * Construct Upload parameters. 50 * 51 * @since 2.3.0 52 * @since 2.4.0 Add the $upload_dir_filter_args argument to the $arguments array 53 * 54 * @param array|string $args { 55 * @type int $original_max_filesize Maximum file size in kilobytes. Defaults to php.ini settings. 56 * @type array $allowed_mime_types List of allowed file extensions (eg: array( 'jpg', 'gif', 'png' ) ). 57 * Defaults to WordPress allowed mime types. 58 * @type string $base_dir Component's upload base directory. Defaults to WordPress 'uploads'. 59 * @type string $action The upload action used when uploading a file, $_POST['action'] must be set 60 * and its value must equal $action {@link wp_handle_upload()} (required). 61 * @type string $file_input The name attribute used in the file input. (required). 62 * @type array $upload_error_strings A list of specific error messages (optional). 63 * @type array $required_wp_files The list of required WordPress core files. Default: array( 'file' ). 64 * @type int $upload_dir_filter_args 1 to receive the original Upload dir array in the Upload dir filter, 0 otherwise. 65 * Defaults to 0 (optional). 66 * } 67 */ 68 public function __construct( $args = '' ) { 69 // Upload action and the file input name are required parameters. 70 if ( empty( $args['action'] ) || empty( $args['file_input'] ) ) { 71 return false; 72 } 73 74 // Sanitize the action ID and the file input name. 75 $this->action = sanitize_key( $args['action'] ); 76 $this->file_input = sanitize_key( $args['file_input'] ); 77 78 /** 79 * Max file size defaults to php ini settings or, in the case of 80 * a multisite config, the root site fileupload_maxk option. 81 */ 82 $this->default_args['original_max_filesize'] = (int) wp_max_upload_size(); 83 84 $params = bp_parse_args( 85 $args, 86 $this->default_args, 87 $this->action . '_upload_params' 88 ); 89 90 foreach ( $params as $key => $param ) { 91 if ( 'upload_error_strings' === $key ) { 92 $this->{$key} = $this->set_upload_error_strings( $param ); 93 94 // Sanitize the base dir. 95 } elseif ( 'base_dir' === $key ) { 96 $this->{$key} = sanitize_title( $param ); 97 98 // Sanitize the upload dir filter arg to pass. 99 } elseif ( 'upload_dir_filter_args' === $key ) { 100 $this->{$key} = (int) $param; 101 102 // Action & File input are already set and sanitized. 103 } elseif ( 'action' !== $key && 'file_input' !== $key ) { 104 $this->{$key} = $param; 105 } 106 } 107 108 // Set the path/url and base dir for uploads. 109 $this->set_upload_dir(); 110 } 111 112 /** 113 * Set upload path and url for the component. 114 * 115 * @since 2.3.0 116 * 117 */ 118 public function set_upload_dir() { 119 // Set the directory, path, & url variables. 120 $this->upload_dir = bp_upload_dir(); 121 122 if ( empty( $this->upload_dir ) ) { 123 return false; 124 } 125 126 $this->upload_path = $this->upload_dir['basedir']; 127 $this->url = $this->upload_dir['baseurl']; 128 129 // Ensure URL is https if SSL is set/forced. 130 if ( is_ssl() ) { 131 $this->url = str_replace( 'http://', 'https://', $this->url ); 132 } 133 134 /** 135 * Custom base dir. 136 * 137 * If the component set this property, set the specific path, url and create the dir 138 */ 139 if ( ! empty( $this->base_dir ) ) { 140 $this->upload_path = trailingslashit( $this->upload_path ) . $this->base_dir; 141 $this->url = trailingslashit( $this->url ) . $this->base_dir; 142 143 // Finally create the base dir. 144 $this->create_dir(); 145 } 146 } 147 148 /** 149 * Set Upload error messages. 150 * 151 * Used into the $overrides argument of BP_Attachment->upload() 152 * 153 * @since 2.3.0 154 * 155 * @param array $param A list of error messages to add to BuddyPress core ones. 156 * @return array $upload_errors The list of upload errors. 157 */ 158 public function set_upload_error_strings( $param = array() ) { 159 /** 160 * Index of the array is the error code 161 * Custom errors will start at 9 code 162 */ 163 $upload_errors = array( 164 0 => __( 'The file was uploaded successfully', 'buddypress' ), 165 1 => __( 'The uploaded file exceeds the maximum allowed file size for this site', 'buddypress' ), 166 167 /* translators: %s: Max file size for the file */ 168 2 => sprintf( __( 'The uploaded file exceeds the maximum allowed file size of: %s', 'buddypress' ), size_format( $this->original_max_filesize ) ), 169 3 => __( 'The uploaded file was only partially uploaded.', 'buddypress' ), 170 4 => __( 'No file was uploaded.', 'buddypress' ), 171 5 => '', 172 6 => __( 'Missing a temporary folder.', 'buddypress' ), 173 7 => __( 'Failed to write file to disk.', 'buddypress' ), 174 8 => __( 'File upload stopped by extension.', 'buddypress' ), 175 ); 176 177 if ( ! array_intersect_key( $upload_errors, (array) $param ) ) { 178 foreach ( $param as $key_error => $error_message ) { 179 $upload_errors[ $key_error ] = $error_message; 180 } 181 } 182 183 return $upload_errors; 184 } 185 186 /** 187 * Include the WordPress core needed files. 188 * 189 * @since 2.3.0 190 */ 191 public function includes() { 192 foreach ( array_unique( $this->required_wp_files ) as $wp_file ) { 193 if ( ! file_exists( ABSPATH . "/wp-admin/includes/{$wp_file}.php" ) ) { 194 continue; 195 } 196 197 require_once( ABSPATH . "/wp-admin/includes/{$wp_file}.php" ); 198 } 199 } 200 201 /** 202 * Upload the attachment. 203 * 204 * @since 2.3.0 205 * 206 * @param array $file The appropriate entry the from $_FILES superglobal. 207 * @param string $upload_dir_filter A specific filter to be applied to 'upload_dir' (optional). 208 * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. 209 * @return array On success, returns an associative array of file attributes. 210 * On failure, returns an array containing the error message 211 * (eg: array( 'error' => $message ) ) 212 */ 213 public function upload( $file, $upload_dir_filter = '', $time = null ) { 214 /** 215 * Upload action and the file input name are required parameters. 216 * 217 * @see BP_Attachment:__construct() 218 */ 219 if ( empty( $this->action ) || empty( $this->file_input ) ) { 220 return false; 221 } 222 223 /** 224 * Add custom rules before enabling the file upload 225 */ 226 add_filter( "{$this->action}_prefilter", array( $this, 'validate_upload' ), 10, 1 ); 227 228 // Set Default overrides. 229 $overrides = array( 230 'action' => $this->action, 231 'upload_error_strings' => $this->upload_error_strings, 232 ); 233 234 /** 235 * Add a mime override if needed 236 * Used to restrict uploads by extensions 237 */ 238 if ( ! empty( $this->allowed_mime_types ) ) { 239 $mime_types = $this->validate_mime_types(); 240 241 if ( ! empty( $mime_types ) ) { 242 $overrides['mimes'] = $mime_types; 243 } 244 } 245 246 /** 247 * If you need to add some overrides we haven't thought of. 248 * 249 * @param array $overrides The wp_handle_upload overrides 250 */ 251 $overrides = apply_filters( 'bp_attachment_upload_overrides', $overrides ); 252 253 $this->includes(); 254 255 /** 256 * If the $base_dir was set when constructing the class, 257 * and no specific filter has been requested, use a default 258 * filter to create the specific $base dir 259 * @see BP_Attachment->upload_dir_filter() 260 */ 261 if ( empty( $upload_dir_filter ) && ! empty( $this->base_dir ) ) { 262 $upload_dir_filter = array( $this, 'upload_dir_filter' ); 263 } 264 265 // Make sure the file will be uploaded in the attachment directory. 266 if ( ! empty( $upload_dir_filter ) ) { 267 add_filter( 'upload_dir', $upload_dir_filter, 10, $this->upload_dir_filter_args ); 268 } 269 270 // Helper for utf-8 filenames. 271 add_filter( 'sanitize_file_name', array( $this, 'sanitize_utf8_filename' ) ); 272 273 // Upload the attachment. 274 $this->attachment = wp_handle_upload( $file[ $this->file_input ], $overrides, $time ); 275 276 remove_filter( 'sanitize_file_name', array( $this, 'sanitize_utf8_filename' ) ); 277 278 // Restore WordPress Uploads data. 279 if ( ! empty( $upload_dir_filter ) ) { 280 remove_filter( 'upload_dir', $upload_dir_filter, 10 ); 281 } 282 283 // Finally return the uploaded file or the error. 284 return $this->attachment; 285 } 286 287 /** 288 * Helper to convert utf-8 characters in filenames to their ASCII equivalent. 289 * 290 * @since 2.9.0 291 * 292 * @param string $retval Filename. 293 * @return string 294 */ 295 public function sanitize_utf8_filename( $retval ) { 296 // PHP 5.4+ or with PECL intl 2.0+ 297 if ( function_exists( 'transliterator_transliterate' ) && seems_utf8( $retval ) ) { 298 $retval = transliterator_transliterate( 'Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove', $retval ); 299 300 // Older. 301 } else { 302 // Use WP's built-in function to convert accents to their ASCII equivalent. 303 $retval = remove_accents( $retval ); 304 305 // Still here? use iconv(). 306 if ( function_exists( 'iconv' ) && seems_utf8( $retval ) ) { 307 $retval = iconv( 'UTF-8', 'ASCII//TRANSLIT//IGNORE', $retval ); 308 } 309 } 310 311 return $retval; 312 } 313 314 /** 315 * Validate the allowed mime types using WordPress allowed mime types. 316 * 317 * In case of a multisite, the mime types are already restricted by 318 * the 'upload_filetypes' setting. BuddyPress will respect this setting. 319 * 320 * @see check_upload_mimes() 321 * 322 * @since 2.3.0 323 * 324 */ 325 protected function validate_mime_types() { 326 $wp_mimes = get_allowed_mime_types(); 327 $valid_mimes = array(); 328 329 // Set the allowed mimes for the upload. 330 foreach ( (array) $this->allowed_mime_types as $ext ) { 331 foreach ( $wp_mimes as $ext_pattern => $mime ) { 332 if ( $ext !== '' && strpos( $ext_pattern, $ext ) !== false ) { 333 $valid_mimes[$ext_pattern] = $mime; 334 } 335 } 336 } 337 return $valid_mimes; 338 } 339 340 /** 341 * Specific upload rules. 342 * 343 * Override this function from your child class to build your specific rules 344 * By default, if an original_max_filesize is provided, a check will be done 345 * on the file size. 346 * 347 * @see BP_Attachment_Avatar->validate_upload() for an example of use 348 * 349 * @since 2.3.0 350 * 351 * @param array $file The temporary file attributes (before it has been moved). 352 * @return array The file. 353 */ 354 public function validate_upload( $file = array() ) { 355 // Bail if already an error. 356 if ( ! empty( $file['error'] ) ) { 357 return $file; 358 } 359 360 if ( ! empty( $this->original_max_filesize ) && $file['size'] > $this->original_max_filesize ) { 361 $file['error'] = 2; 362 } 363 364 // Return the file. 365 return $file; 366 } 367 368 /** 369 * Default filter to save the attachments. 370 * 371 * @since 2.3.0 372 * @since 2.4.0 Add the $upload_dir parameter to the method 373 * 374 * regarding to context 375 * 376 * @param array $upload_dir The original Uploads dir. 377 * @return array The upload directory data. 378 */ 379 public function upload_dir_filter( $upload_dir = array() ) { 380 381 /** 382 * Filters the component's upload directory. 383 * 384 * @since 2.3.0 385 * @since 2.4.0 Include the original Upload directory as the second parameter of the filter. 386 * 387 * @param array $value Array containing the path, URL, and other helpful settings. 388 * @param array $upload_dir The original Uploads dir. 389 */ 390 return apply_filters( 'bp_attachment_upload_dir', array( 391 'path' => $this->upload_path, 392 'url' => $this->url, 393 'subdir' => false, 394 'basedir' => $this->upload_path, 395 'baseurl' => $this->url, 396 'error' => false 397 ), $upload_dir ); 398 } 399 400 /** 401 * Create the custom base directory for the component uploads. 402 * 403 * Override this function in your child class to run specific actions. 404 * (eg: add an .htaccess file) 405 * 406 * @since 2.3.0 407 * 408 */ 409 public function create_dir() { 410 // Bail if no specific base dir is set. 411 if ( empty( $this->base_dir ) ) { 412 return false; 413 } 414 415 // Check if upload path already exists. 416 if ( ! is_dir( $this->upload_path ) ) { 417 418 // If path does not exist, attempt to create it. 419 if ( ! wp_mkdir_p( $this->upload_path ) ) { 420 return false; 421 } 422 } 423 424 // Directory exists. 425 return true; 426 } 427 428 /** 429 * Crop an image file. 430 * 431 * @since 2.3.0 432 * 433 * @param array $args { 434 * @type string $original_file The source file (absolute path) for the Attachment. 435 * @type int $crop_x The start x position to crop from. 436 * @type int $crop_y The start y position to crop from. 437 * @type int $crop_w The width to crop. 438 * @type int $crop_h The height to crop. 439 * @type int $dst_w The destination width. 440 * @type int $dst_h The destination height. 441 * @type int $src_abs Optional. If the source crop points are absolute. 442 * @type string $dst_file Optional. The destination file to write to. 443 * } 444 * 445 * @return string|WP_Error New filepath on success, WP_Error on failure. 446 */ 447 public function crop( $args = array() ) { 448 $wp_error = new WP_Error(); 449 450 $r = bp_parse_args( 451 $args, 452 array( 453 'original_file' => '', 454 'crop_x' => 0, 455 'crop_y' => 0, 456 'crop_w' => 0, 457 'crop_h' => 0, 458 'dst_w' => 0, 459 'dst_h' => 0, 460 'src_abs' => false, 461 'dst_file' => false, 462 ), 463 'bp_attachment_crop_args' 464 ); 465 466 if ( empty( $r['original_file'] ) || ! file_exists( $r['original_file'] ) ) { 467 $wp_error->add( 'crop_error', __( 'Cropping the file failed: missing source file.', 'buddypress' ) ); 468 return $wp_error; 469 } 470 471 // Check image file pathes. 472 $path_error = __( 'Cropping the file failed: the file path is not allowed.', 'buddypress' ); 473 474 // Make sure it's coming from an uploaded file. 475 if ( false === strpos( $r['original_file'], $this->upload_path ) ) { 476 $wp_error->add( 'crop_error', $path_error ); 477 return $wp_error; 478 } 479 480 /** 481 * If no destination file is provided, WordPress will use a default name 482 * and will write the file in the source file's folder. 483 * If a destination file is provided, we need to make sure it's going into uploads. 484 */ 485 if ( ! empty( $r['dst_file'] ) && false === strpos( $r['dst_file'], $this->upload_path ) ) { 486 $wp_error->add( 'crop_error', $path_error ); 487 return $wp_error; 488 } 489 490 // Check image file types. 491 $check_types = array( 'src_file' => array( 'file' => $r['original_file'], 'error' => _x( 'source file', 'Attachment source file', 'buddypress' ) ) ); 492 if ( ! empty( $r['dst_file'] ) ) { 493 $check_types['dst_file'] = array( 'file' => $r['dst_file'], 'error' => _x( 'destination file', 'Attachment destination file', 'buddypress' ) ); 494 } 495 496 /** 497 * WordPress image supported types. 498 * @see wp_attachment_is() 499 */ 500 $supported_image_types = array( 501 'jpg' => 1, 502 'jpeg' => 1, 503 'jpe' => 1, 504 'gif' => 1, 505 'png' => 1, 506 ); 507 508 foreach ( $check_types as $file ) { 509 $is_image = wp_check_filetype( $file['file'] ); 510 $ext = $is_image['ext']; 511 512 if ( empty( $ext ) || empty( $supported_image_types[ $ext ] ) ) { 513 $wp_error->add( 514 'crop_error', 515 sprintf( 516 /* translators: %s: image file extension */ 517 __( 'Cropping the file failed: %s is not a supported image file.', 'buddypress' ), 518 $file['error'] 519 ) 520 ); 521 522 return $wp_error; 523 } 524 } 525 526 // Add the image.php to the required WordPress files, if it's not already the case. 527 $required_files = array_flip( $this->required_wp_files ); 528 if ( ! isset( $required_files['image'] ) ) { 529 $this->required_wp_files[] = 'image'; 530 } 531 532 // Load the files. 533 $this->includes(); 534 535 // Finally crop the image. 536 return wp_crop_image( $r['original_file'], (int) $r['crop_x'], (int) $r['crop_y'], (int) $r['crop_w'], (int) $r['crop_h'], (int) $r['dst_w'], (int) $r['dst_h'], $r['src_abs'], $r['dst_file'] ); 537 } 538 539 /** 540 * Build script datas for the Uploader UI. 541 * 542 * Override this method from your child class to build the script datas. 543 * 544 * @since 2.3.0 545 * 546 * @return array The javascript localization data. 547 */ 548 public function script_data() { 549 $script_data = array( 550 'action' => $this->action, 551 'file_data_name' => $this->file_input, 552 'max_file_size' => $this->original_max_filesize, 553 'feedback_messages' => array( 554 1 => __( 'Sorry, uploading the file failed.', 'buddypress' ), 555 2 => __( 'File successfully uploaded.', 'buddypress' ), 556 ), 557 ); 558 559 return $script_data; 560 } 561 562 /** 563 * Adds a new revision of a file. 564 * 565 * @since 10.0.0 566 * 567 * @param string $attachment_type The attachement type (eg: avatar). 568 * @param array $args { 569 * @type string $file_abspath The source file (absolute path) for the attachment. 570 * @type string $file_id Optional. The file ID to use as a suffix for the revision directory. 571 * } 572 * @return object|WP_Error An object informing about the URL an Path to a revision file, a WP_Error object on failure. 573 */ 574 public function add_revision( $attachment_type, $args = array() ) { 575 $r = bp_parse_args( 576 $args, 577 array( 578 'file_abspath' => '', 579 'file_id' => '', 580 ), 581 'attachment_' . $attachment_type . '_add_revision' 582 ); 583 584 if ( ! $r['file_abspath'] ) { 585 return new WP_Error( 'missing_parameter', __( 'The absolute path to your file is missing.', 'buddypress' ) ); 586 587 // Make sure it's coming from an uploaded file. 588 } elseif ( false === strpos( $r['file_abspath'], $this->upload_path ) ) { 589 return new WP_Error( 'forbidden_path', __( 'The absolute path to your file is not allowed.', 'buddypress' ) ); 590 591 } else { 592 $filepath = $r['file_abspath']; 593 } 594 595 $dirname = trailingslashit( dirname( $filepath ) ); 596 $filename = sanitize_file_name( wp_basename( $filepath ) ); 597 598 if ( ! $r['file_id'] ) { 599 $r['file_id'] = $filename; 600 } 601 602 $file_id = wp_hash( $r['file_id'] ); 603 604 // Set the revision name & dir. 605 $revision_name = ''; 606 $revision_dir = $dirname . '._revisions_' . $file_id; 607 608 // Avatars and Cover Images are specific attachments. 609 if ( 'avatar' === $attachment_type || 'cover_image' === $attachment_type ) { 610 $revision_dir = $dirname . 'history'; 611 } 612 613 // Create the revision directory if it doesn't exist yet. 614 if ( ! is_dir( $revision_dir ) ) { 615 mkdir( $revision_dir ); 616 } 617 618 $revision_name = wp_unique_filename( $revision_dir, $filename ); 619 $revision_path = trailingslashit( $revision_dir ) . $revision_name; 620 621 if ( ! rename( $filepath, $revision_path ) ) { 622 return new WP_Error( 'adding_revision_failed', __( 'An unexpected error occured while adding the revision.', 'buddypress' ) ); 623 } 624 625 return (object) array( 626 'url' => str_replace( trailingslashit( $this->upload_path ), trailingslashit( $this->url ), $revision_path ), 627 'path' => $revision_path, 628 ); 629 } 630 631 /** 632 * Get full data for an image 633 * 634 * @since 2.4.0 635 * 636 * @param string $file Absolute path to the uploaded image. 637 * @return bool|array An associate array containing the width, height and metadatas. 638 * False in case an important image attribute is missing. 639 */ 640 public static function get_image_data( $file ) { 641 // Try to get image basic data. 642 list( $width, $height, $sourceImageType ) = @getimagesize( $file ); 643 644 // No need to carry on if we couldn't get image's basic data. 645 if ( is_null( $width ) || is_null( $height ) || is_null( $sourceImageType ) ) { 646 return false; 647 } 648 649 // Initialize the image data. 650 $image_data = array( 651 'width' => $width, 652 'height' => $height, 653 ); 654 655 /** 656 * Make sure the wp_read_image_metadata function is reachable for the old Avatar UI 657 * or if WordPress < 3.9 (New Avatar UI is not available in this case) 658 */ 659 if ( ! function_exists( 'wp_read_image_metadata' ) ) { 660 require_once( ABSPATH . 'wp-admin/includes/image.php' ); 661 } 662 663 // Now try to get image's meta data. 664 $meta = wp_read_image_metadata( $file ); 665 if ( ! empty( $meta ) ) { 666 $image_data['meta'] = $meta; 667 } 668 669 /** 670 * Filter here to add/remove/edit data to the image full data 671 * 672 * @since 2.4.0 673 * 674 * @param array $image_data An associate array containing the width, height and metadatas. 675 */ 676 return apply_filters( 'bp_attachments_get_image_data', $image_data ); 677 } 678 679 /** 680 * Edit an image file to resize it or rotate it 681 * 682 * @since 2.4.0 683 * 684 * @param string $attachment_type The attachment type (eg: avatar or cover_image). Required. 685 * @param array $args { 686 * @type string $file Absolute path to the image file (required). 687 * @type int $max_w Max width attribute for the editor's resize method (optional). 688 * @type int $max_h Max height attribute for the editor's resize method (optional). 689 * @type bool $crop Crop attribute for the editor's resize method (optional). 690 * @type float $rotate Angle for the editor's rotate method (optional). 691 * @type int $quality Compression quality on a 1-100% scale (optional). 692 * @type bool $save Whether to use the editor's save method or not (optional). 693 * } 694 * @return string|WP_Image_Editor|WP_Error The edited image path or the WP_Image_Editor object in case of success, 695 * an WP_Error object otherwise. 696 */ 697 public static function edit_image( $attachment_type, $args = array() ) { 698 if ( empty( $attachment_type ) ) { 699 return new WP_Error( 'missing_parameter' ); 700 } 701 702 $r = bp_parse_args( 703 $args, 704 array( 705 'file' => '', 706 'max_w' => 0, 707 'max_h' => 0, 708 'crop' => false, 709 'rotate' => 0, 710 'quality' => 90, 711 'save' => true, 712 ), 713 'attachment_' . $attachment_type . '_edit_image' 714 ); 715 716 // Make sure we have to edit the image. 717 if ( empty( $r['max_w'] ) && empty( $r['max_h'] ) && empty( $r['rotate'] ) && empty( $r['file'] ) ) { 718 return new WP_Error( 'missing_parameter' ); 719 } 720 721 // Get the image editor. 722 $editor = wp_get_image_editor( $r['file'] ); 723 724 if ( is_wp_error( $editor ) ) { 725 return $editor; 726 } 727 728 $editor->set_quality( $r['quality'] ); 729 730 if ( ! empty( $r['rotate'] ) ) { 731 $rotated = $editor->rotate( $r['rotate'] ); 732 733 // Stop in case of error. 734 if ( is_wp_error( $rotated ) ) { 735 return $rotated; 736 } 737 } 738 739 if ( ! empty( $r['max_w'] ) || ! empty( $r['max_h'] ) ) { 740 $resized = $editor->resize( $r['max_w'], $r['max_h'], $r['crop'] ); 741 742 // Stop in case of error. 743 if ( is_wp_error( $resized ) ) { 744 return $resized; 745 } 746 } 747 748 // Use the editor save method to get a path to the edited image. 749 if ( true === $r['save'] ) { 750 return $editor->save( $editor->generate_filename() ); 751 752 // Need to do some other edit actions or use a specific method to save file. 753 } else { 754 return $editor; 755 } 756 } 757 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Dec 6 01:00:58 2024 | Cross-referenced by PHPXref 0.7.1 |