Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | new WPCOM_JSON_API_Upload_Media_v1_1_Endpoint( array( |
||
| 4 | 'description' => 'Upload a new piece of media.', |
||
| 5 | 'allow_cross_origin_request' => true, |
||
| 6 | 'allow_upload_token_auth' => true, |
||
| 7 | 'group' => 'media', |
||
| 8 | 'stat' => 'media:new', |
||
| 9 | 'min_version' => '1.1', |
||
| 10 | 'max_version' => '1.1', |
||
| 11 | 'method' => 'POST', |
||
| 12 | 'path' => '/sites/%s/media/new', |
||
| 13 | 'path_labels' => array( |
||
| 14 | '$site' => '(int|string) Site ID or domain', |
||
| 15 | ), |
||
| 16 | |||
| 17 | 'request_format' => array( |
||
| 18 | 'media' => "(media) An array of media to attach to the post. To upload media, the entire request should be multipart/form-data encoded. Accepts jpg, jpeg, png, gif, pdf, doc, ppt, odt, pptx, docx, pps, ppsx, xls, xlsx, key. Audio and Video may also be available. See <code>allowed_file_types</code> in the options response of the site endpoint.<br /><br /><strong>Example</strong>:<br />" . |
||
| 19 | "<code>curl \<br />--form 'media[]=@/path/to/file.jpg' \<br />-H 'Authorization: BEARER your-token' \<br />'https://public-api.wordpress.com/rest/v1/sites/123/media/new'</code>", |
||
| 20 | 'media_urls' => "(array) An array of URLs to upload to the post. Errors produced by media uploads, if any, will be in `media_errors` in the response.", |
||
| 21 | 'attrs' => "(array) An array of attributes (`title`, `description`, `caption` `alt` for images, `artist` for audio, `album` for audio, and `parent_id`) are supported to assign to the media uploaded via the `media` or `media_urls` properties. You must use a numeric index for the keys of `attrs` which follows the same sequence as `media` and `media_urls`. <br /><br /><strong>Example</strong>:<br />" . |
||
| 22 | "<code>curl \<br />--form 'media[]=@/path/to/file1.jpg' \<br />--form 'media_urls[]=http://example.com/file2.jpg' \<br /> \<br />--form 'attrs[0][caption]=This will be the caption for file1.jpg' \<br />--form 'attrs[1][title]=This will be the title for file2.jpg' \<br />-H 'Authorization: BEARER your-token' \<br />'https://public-api.wordpress.com/rest/v1/sites/123/posts/new'</code>", |
||
| 23 | ), |
||
| 24 | |||
| 25 | 'response_format' => array( |
||
| 26 | 'media' => '(array) Array of uploaded media objects', |
||
| 27 | 'errors' => '(array) Array of error messages of uploading media failures', |
||
| 28 | ), |
||
| 29 | |||
| 30 | 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/media/new', |
||
| 31 | 'example_request_data' => array( |
||
| 32 | 'headers' => array( |
||
| 33 | 'authorization' => 'Bearer YOUR_API_TOKEN', |
||
| 34 | ), |
||
| 35 | 'body' => array( |
||
| 36 | 'media_urls' => 'https://s.w.org/about/images/logos/codeispoetry-rgb.png', |
||
| 37 | ), |
||
| 38 | ) |
||
| 39 | ) ); |
||
| 40 | |||
| 41 | class WPCOM_JSON_API_Upload_Media_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint { |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @param string $path |
||
| 45 | * @param int $blog_id |
||
| 46 | * |
||
| 47 | * @return array|int|WP_Error|void |
||
| 48 | */ |
||
| 49 | function callback( $path = '', $blog_id = 0 ) { |
||
| 50 | $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) ); |
||
| 51 | if ( is_wp_error( $blog_id ) ) { |
||
| 52 | return $blog_id; |
||
| 53 | } |
||
| 54 | |||
| 55 | if ( ! current_user_can( 'upload_files' ) && ! $this->api->is_authorized_with_upload_token() ) { |
||
|
0 ignored issues
–
show
|
|||
| 56 | return new WP_Error( 'unauthorized', 'User cannot upload media.', 403 ); |
||
|
0 ignored issues
–
show
The call to
WP_Error::__construct() has too many arguments starting with 'unauthorized'.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 57 | } |
||
| 58 | |||
| 59 | $input = $this->input( true ); |
||
| 60 | |||
| 61 | $media_files = ! empty( $input['media'] ) ? $input['media'] : array(); |
||
| 62 | $media_urls = ! empty( $input['media_urls'] ) ? $input['media_urls'] : array(); |
||
| 63 | $media_attrs = ! empty( $input['attrs'] ) ? $input['attrs'] : array(); |
||
| 64 | |||
| 65 | if ( empty( $media_files ) && empty( $media_urls ) ) { |
||
| 66 | return new WP_Error( 'invalid_input', 'No media provided in input.' ); |
||
|
0 ignored issues
–
show
The call to
WP_Error::__construct() has too many arguments starting with 'invalid_input'.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 67 | } |
||
| 68 | |||
| 69 | $is_jetpack_site = false; |
||
| 70 | if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { |
||
| 71 | // For jetpack sites, we send the media via a different method, because the sync is very different. |
||
| 72 | $jetpack_sync = Jetpack_Media_Sync::summon( $blog_id ); |
||
| 73 | $is_jetpack_site = $jetpack_sync->is_jetpack_site(); |
||
| 74 | } |
||
| 75 | |||
| 76 | $jetpack_media_files = array(); |
||
| 77 | $other_media_files = array(); |
||
| 78 | $media_items = array(); |
||
| 79 | $errors = array(); |
||
| 80 | |||
| 81 | // We're splitting out videos for Jetpack sites |
||
| 82 | foreach ( $media_files as $media_item ) { |
||
| 83 | if ( preg_match( '@^video/@', $media_item['type'] ) && $is_jetpack_site ) { |
||
| 84 | $jetpack_media_files[] = $media_item; |
||
| 85 | |||
| 86 | } else { |
||
| 87 | $other_media_files[] = $media_item; |
||
| 88 | } |
||
| 89 | } |
||
| 90 | |||
| 91 | // New Jetpack / VideoPress media upload processing |
||
| 92 | if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { |
||
| 93 | if ( count( $jetpack_media_files ) > 0 ) { |
||
| 94 | add_filter( 'upload_mimes', array( $this, 'allow_video_uploads' ) ); |
||
| 95 | |||
| 96 | $media_items = $jetpack_sync->upload_media( $jetpack_media_files, $this->api ); |
||
| 97 | |||
| 98 | $errors = $jetpack_sync->get_errors(); |
||
| 99 | |||
| 100 | foreach ( $media_items as & $media_item ) { |
||
| 101 | // More than likely a post has not been created yet, so we pass in the media item we |
||
| 102 | // got back from the Jetpack site. |
||
| 103 | $post = (object) $media_item['post']; |
||
| 104 | $media_item = $this->get_media_item_v1_1( $post->ID, $post, $media_item['file'] ); |
||
| 105 | } |
||
| 106 | } |
||
| 107 | } |
||
| 108 | |||
| 109 | // Normal WPCOM upload processing |
||
| 110 | if ( count( $other_media_files ) > 0 || count( $media_urls ) > 0 ) { |
||
| 111 | if ( is_multisite() ) { // Do not check for available space in non multisites. |
||
| 112 | add_filter( 'wp_handle_upload_prefilter', array( $this, 'check_upload_size' ), 9 ); // used for direct media uploads. |
||
| 113 | add_filter( 'wp_handle_sideload_prefilter', array( $this, 'check_upload_size' ), 9 ); // used for uploading media via url. |
||
| 114 | } |
||
| 115 | |||
| 116 | $create_media = $this->handle_media_creation_v1_1( $other_media_files, $media_urls, $media_attrs ); |
||
| 117 | $media_ids = $create_media['media_ids']; |
||
| 118 | $errors = $create_media['errors']; |
||
| 119 | |||
| 120 | $media_items = array(); |
||
| 121 | foreach ( $media_ids as $media_id ) { |
||
| 122 | $media_items[] = $this->get_media_item_v1_1( $media_id ); |
||
| 123 | } |
||
| 124 | } |
||
| 125 | |||
| 126 | if ( count( $media_items ) <= 0 ) { |
||
| 127 | return $this->api->output_early( 400, array( 'errors' => $this->rewrite_generic_upload_error( $errors ) ) ); |
||
| 128 | } |
||
| 129 | |||
| 130 | $results = array(); |
||
| 131 | foreach ( $media_items as $media_item ) { |
||
| 132 | if ( is_wp_error( $media_item ) ) { |
||
| 133 | $errors[] = array( 'file' => $media_item['ID'], 'error' => $media_item->get_error_code(), 'message' => $media_item->get_error_message() ); |
||
| 134 | |||
| 135 | } else { |
||
| 136 | $results[] = $media_item; |
||
| 137 | } |
||
| 138 | } |
||
| 139 | |||
| 140 | $response = array( 'media' => $results ); |
||
| 141 | |||
| 142 | if ( count( $errors ) > 0 ) { |
||
| 143 | $response['errors'] = $this->rewrite_generic_upload_error( $errors ); |
||
| 144 | } |
||
| 145 | |||
| 146 | return $response; |
||
| 147 | } |
||
| 148 | |||
| 149 | /** |
||
| 150 | * This changes the generic "upload_error" code to something more meaningful if possible |
||
| 151 | * |
||
| 152 | * @param array $errors Errors for the uploaded file. |
||
| 153 | * @return array The same array with an improved error message. |
||
| 154 | */ |
||
| 155 | function rewrite_generic_upload_error( $errors ) { |
||
| 156 | foreach ( $errors as $k => $error ) { |
||
| 157 | if ( 'upload_error' === $error['error'] && false !== strpos( $error['message'], '|' ) ) { |
||
| 158 | list( $errors[ $k ]['error'], $errors[ $k ]['message'] ) = explode( '|', $error['message'], 2 ); |
||
| 159 | } |
||
| 160 | } |
||
| 161 | return $errors; |
||
| 162 | } |
||
| 163 | |||
| 164 | /** |
||
| 165 | * Determine if uploaded file exceeds space quota on multisite. |
||
| 166 | * |
||
| 167 | * This is a copy of the core function with added functionality, synced |
||
| 168 | * with this with WP_REST_Attachments_Controller::check_upload_size() |
||
| 169 | * to allow for specifying a better error message. |
||
| 170 | * |
||
| 171 | * @param array $file $_FILES array for a given file. |
||
| 172 | * @return array Maybe extended with an error message. |
||
| 173 | */ |
||
| 174 | function check_upload_size( $file ) { |
||
| 175 | if ( get_site_option( 'upload_space_check_disabled' ) ) { |
||
| 176 | return $file; |
||
| 177 | } |
||
| 178 | |||
| 179 | if ( isset( $file['error'] ) && $file['error'] > 0 ) { // There's already an error. Error Codes Reference: https://www.php.net/manual/en/features.file-upload.errors.php . |
||
| 180 | return $file; |
||
| 181 | } |
||
| 182 | |||
| 183 | if ( defined( 'WP_IMPORTING' ) ) { |
||
| 184 | return $file; |
||
| 185 | } |
||
| 186 | |||
| 187 | $space_left = get_upload_space_available(); |
||
| 188 | |||
| 189 | $file_size = filesize( $file['tmp_name'] ); |
||
| 190 | if ( $space_left < $file_size ) { |
||
| 191 | /* translators: %s: Required disk space in kilobytes. */ |
||
| 192 | $file['error'] = 'rest_upload_limited_space|' . sprintf( __( 'Not enough space to upload. %s KB needed.', 'default' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) ); |
||
| 193 | } |
||
| 194 | |||
| 195 | if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) { |
||
| 196 | /* translators: %s: Maximum allowed file size in kilobytes. */ |
||
| 197 | $file['error'] = 'rest_upload_file_too_big|' . sprintf( __( 'This file is too big. Files must be less than %s KB in size.', 'default' ), get_site_option( 'fileupload_maxk', 1500 ) ); |
||
| 198 | } |
||
| 199 | |||
| 200 | if ( upload_is_user_over_quota( false ) ) { |
||
| 201 | $file['error'] = 'rest_upload_user_quota_exceeded|' . __( 'You have used your space quota. Please delete files before uploading.', 'default' ); |
||
| 202 | } |
||
| 203 | |||
| 204 | return $file; |
||
| 205 | } |
||
| 206 | /** |
||
| 207 | * Force to use the WPCOM API instead of proxy back to the Jetpack API if the blog is a paid Jetpack |
||
| 208 | * blog w/ the VideoPress module enabled AND the uploaded file is a video. |
||
| 209 | * |
||
| 210 | * @param int $blog_id |
||
| 211 | * @return bool |
||
| 212 | */ |
||
| 213 | function force_wpcom_request( $blog_id ) { |
||
| 214 | |||
| 215 | // We don't need to do anything if VideoPress is not enabled for the blog. |
||
| 216 | if ( ! is_videopress_enabled_on_jetpack_blog( $blog_id ) ) { |
||
| 217 | return false; |
||
| 218 | } |
||
| 219 | |||
| 220 | // Check to see if the upload is not a video type, if not then return false. |
||
| 221 | $input = $this->input( true ); |
||
| 222 | $media_files = ! empty( $input['media'] ) ? $input['media'] : array(); |
||
| 223 | |||
| 224 | if ( empty( $media_files ) ) { |
||
| 225 | return false; |
||
| 226 | } |
||
| 227 | |||
| 228 | foreach ( $media_files as $media_item ) { |
||
| 229 | if ( ! preg_match( '@^video/@', $media_item['type'] ) ) { |
||
| 230 | return false; |
||
| 231 | } |
||
| 232 | } |
||
| 233 | |||
| 234 | // The API request should be for a blog w/ Jetpack, A valid plan, has VideoPress enabled, |
||
| 235 | // and is a video file. Let's let it through. |
||
| 236 | return true; |
||
| 237 | } |
||
| 238 | } |
||
| 239 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.