| @@ -1,162 +1,66 @@ | ||
| 1 | 1 | <?php |
| 2 | -defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' ); | |
| 2 | +defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' ); | |
| 3 | 3 | |
| 4 | 4 | /** |
| 5 | - * Process an image with Imagify. | |
| 5 | + * Run an async job to optimize images in background. | |
| 6 | 6 | * |
| 7 | - * @since 1.0 | |
| 7 | + * @param array $body Contains the usual $_POST. | |
| 8 | 8 | * |
| 9 | - * @param string $file_path Absolute path to the image file. | |
| 10 | - * @param bool $backup Force a backup of the original file. | |
| 11 | - * @param int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal). | |
| 12 | - * @param array $resize The resize parameters (with & height). | |
| 13 | - * @param bool $keep_exif To keep exif data or not | |
| 14 | - * @return obj|array Error message | Optimized image data | |
| 9 | + * @since 1.4 | |
| 15 | 10 | */ |
| 16 | -function do_imagify( $file_path, $backup, $optimization_level, $resize = array(), $keep_exif = false ) { | |
| 17 | - $errors = new WP_Error(); | |
| 18 | - | |
| 11 | +function imagify_do_async_job( $body ) { | |
| 12 | + $args = [ | |
| 13 | + 'timeout' => 0.01, | |
| 14 | + 'blocking' => false, | |
| 15 | + 'body' => $body, | |
| 16 | + 'cookies' => isset( $_COOKIE ) && is_array( $_COOKIE ) ? $_COOKIE : [], | |
| 17 | + 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), | |
| 18 | + ]; | |
| 19 | + | |
| 19 | 20 | /** |
| 20 | - * Filter the attachment path | |
| 21 | + * Filter the arguments used to launch an async job. | |
| 21 | 22 | * |
| 22 | - * @since 1.2 | |
| 23 | + * @since 1.6.6 | |
| 24 | + * @author Grégory Viguier | |
| 23 | 25 | * |
| 24 | - * @param string $file_path The attachment path | |
| 26 | + * @param array $args An array of arguments passed to wp_remote_post(). | |
| 25 | 27 | */ |
| 26 | - $file_path = apply_filters( 'imagify_file_path', $file_path ); | |
| 27 | - | |
| 28 | - // Check if the Imagify servers & the API are accessible | |
| 29 | - if ( ! is_imagify_servers_up() ) { | |
| 30 | - $errors->add( 'api_server_down', __( 'Sorry, our servers are temporarily unaccessible. Please, try again in a couple of minutes.', 'imagify' ) ); | |
| 31 | - return $errors; | |
| 32 | - } | |
| 33 | - | |
| 34 | - // Check if external HTTP requests are blocked. | |
| 35 | - if ( is_imagify_blocked() ) { | |
| 36 | - $errors->add( 'http_block_external', __( 'External HTTP requests are blocked', 'imagify' ) ); | |
| 37 | - return $errors; | |
| 38 | - } | |
| 39 | - | |
| 40 | - // Check that file path isn't empty | |
| 41 | - if ( empty( $file_path ) ) { | |
| 42 | - $errors->add( 'empty_path', __( 'File path is empty', 'imagify' ) ); | |
| 43 | - return $errors; | |
| 44 | - } | |
| 28 | + $args = apply_filters( 'imagify_do_async_job_args', $args ); | |
| 45 | 29 | |
| 46 | - // Check that the file exists | |
| 47 | - if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) { | |
| 48 | - $errors->add( 'file_not_found', sprintf( __( 'Could not find %s', 'imagify' ), $file_path ) ); | |
| 49 | - } | |
| 50 | - | |
| 51 | - // Check that the file is writable | |
| 52 | - if ( ! is_writable( dirname( $file_path ) ) ) { | |
| 53 | - $errors->add( 'not_writable', sprintf( __( "%s is not writable", 'imagify' ), dirname( $file_path ) ) ); | |
| 54 | - return $errors; | |
| 55 | - } | |
| 56 | - | |
| 57 | - // Get file size | |
| 58 | - $file_size = file_exists( $file_path ) ? filesize( $file_path ) : 0; | |
| 59 | - | |
| 60 | - // Check that file exists | |
| 61 | - if ( 0 == $file_size ) { | |
| 62 | - $errors->add( 'image_not_found', sprintf( __( 'Skipped (%s), image not found.', 'imagify' ), size_format( $file_size ) ) ); | |
| 63 | - return $errors; | |
| 64 | - } | |
| 65 | - | |
| 66 | 30 | /** |
| 67 | - * Fires before to optimize the Image with Imagify. | |
| 68 | - * | |
| 69 | - * @since 1.0 | |
| 70 | - * | |
| 71 | - * @param string $file_path Absolute path to the image file. | |
| 72 | - * @param bool $backup Force a backup of the original file. | |
| 73 | - */ | |
| 74 | - do_action( 'before_do_imagify', $file_path, $backup ); | |
| 31 | + * It can be a XML-RPC request. The problem is that XML-RPC doesn't use cookies. | |
| 32 | + */ | |
| 33 | + if ( defined( 'XMLRPC_REQUEST' ) && get_current_user_id() ) { | |
| 34 | + /** | |
| 35 | + * In old WP versions, the field "option_name" in the wp_options table was limited to 64 characters. | |
| 36 | + * From 64, remove 19 characters for "_transient_timeout_" = 45. | |
| 37 | + * Then remove 12 characters for "imagify_rpc_" (transient name) = 33. | |
| 38 | + * Luckily, a md5 is 32 characters long. | |
| 39 | + */ | |
| 40 | + $rpc_id = md5( maybe_serialize( $body ) ); | |
| 75 | 41 | |
| 76 | - // Send image for optimization and fetch the response | |
| 77 | - $response = upload_imagify_image( | |
| 78 | - array( | |
| 79 | - 'image' => curl_file_create( $file_path ), | |
| 80 | - 'data' => json_encode( | |
| 81 | - array( | |
| 82 | - 'aggressive' => ( 1 === (int) $optimization_level ) ? true : false, | |
| 83 | - 'ultra' => ( 2 === (int) $optimization_level ) ? true : false, | |
| 84 | - 'resize' => $resize, | |
| 85 | - 'keep_exif' => $keep_exif | |
| 86 | - ) | |
| 87 | - ) | |
| 88 | - ) | |
| 89 | - ); | |
| 42 | + // Send the request to our RPC bridge instead. | |
| 43 | + $args['body']['imagify_rpc_action'] = $args['body']['action']; | |
| 44 | + $args['body']['action'] = 'imagify_rpc'; | |
| 45 | + $args['body']['imagify_rpc_id'] = $rpc_id; | |
| 46 | + $args['body']['imagify_rpc_nonce'] = wp_create_nonce( 'imagify_rpc_' . $rpc_id ); | |
| 90 | 47 | |
| 91 | - // Check status code | |
| 92 | - if( is_wp_error( $response ) ) { | |
| 93 | - $errors->add( 'api_error', $response->get_error_message() ); | |
| 94 | - return $errors; | |
| 48 | + // Since we can't send cookies to keep the user logged in, store the user ID in a transient. | |
| 49 | + set_transient( 'imagify_rpc_' . $rpc_id, get_current_user_id(), 30 ); | |
| 95 | 50 | } |
| 96 | 51 | |
| 97 | - // Create a backup file | |
| 98 | - if ( $backup ) { | |
| 99 | - $backup_path = get_imagify_attachment_backup_path( $file_path ); | |
| 100 | - $backup_path_info = pathinfo( $backup_path ); | |
| 52 | + $url = admin_url( 'admin-ajax.php' ); | |
| 101 | 53 | |
| 102 | - wp_mkdir_p( $backup_path_info['dirname'] ); | |
| 103 | - | |
| 104 | - // TO DO - check and send a error message if the backup can't be created | |
| 105 | - @copy( $file_path, $backup_path ); | |
| 106 | - imagify_chmod_file( $backup_path ); | |
| 107 | - } | |
| 108 | - | |
| 109 | - if ( ! function_exists( 'download_url' ) ) { | |
| 110 | - require( ABSPATH . 'wp-admin/includes/file.php' ); | |
| 111 | - } | |
| 112 | - | |
| 113 | - $temp_file = download_url( $response->image ); | |
| 114 | - | |
| 115 | - if ( is_wp_error( $temp_file ) ) { | |
| 116 | - $errors->add( 'temp_file_not_found', $temp_file->get_error_message() ); | |
| 117 | - return $errors; | |
| 118 | - } | |
| 119 | - | |
| 120 | - @rename( $temp_file, $file_path ); | |
| 121 | - imagify_chmod_file( $file_path ); | |
| 122 | - | |
| 123 | - // If temp file still exists, delete it | |
| 124 | - if ( file_exists( $temp_file ) ) { | |
| 125 | - unlink( $temp_file ); | |
| 126 | - } | |
| 127 | - | |
| 128 | 54 | /** |
| 129 | - * Fires after to optimize the Image with Imagify. | |
| 55 | + * Filter the URL to use for async jobs. | |
| 130 | 56 | * |
| 131 | - * @since 1.0 | |
| 57 | + * @since 1.9.5 | |
| 58 | + * @author Grégory Viguier | |
| 132 | 59 | * |
| 133 | - * @param string $file_path Absolute path to the image file. | |
| 134 | - * @param bool $backup Force a backup of the original file. | |
| 135 | - */ | |
| 136 | - do_action( 'after_do_imagify', $file_path, $backup ); | |
| 60 | + * @param string $url An URL. | |
| 61 | + * @param array $args An array of arguments passed to wp_remote_post(). | |
| 62 | + */ | |
| 63 | + $url = apply_filters( 'imagify_async_job_url', $url, $args ); | |
| 137 | 64 | |
| 138 | - return $response; | |
| 65 | + wp_remote_post( $url, $args ); | |
| 139 | 66 | } |
| 140 | - | |
| 141 | -/** | |
| 142 | - * Run an async job to optimize images in background | |
| 143 | - * | |
| 144 | - * @param $body (array) Contains the usual $_POST | |
| 145 | - * | |
| 146 | - * @since 1.4 | |
| 147 | - **/ | |
| 148 | -function imagify_do_async_job( $body ) { | |
| 149 | - if ( isset( $body['transient_id'] ) ) { | |
| 150 | - set_transient( 'imagify-async-in-progress-' . $body['transient_id'], true ); | |
| 151 | - } | |
| 152 | - | |
| 153 | - $args = array( | |
| 154 | - 'timeout' => 0.01, | |
| 155 | - 'blocking' => false, | |
| 156 | - 'body' => $body, | |
| 157 | - 'cookies' => $_COOKIE, | |
| 158 | - 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), | |
| 159 | - ); | |
| 160 | - | |
| 161 | - wp_remote_post( admin_url( 'admin-ajax.php' ), $args ); | |
| 162 | -} | |