11

I need your help to upload a media image in my wordpress blog via the Wp-rest-api v2 and Oauth2 authentication.

I did not find in the REST API documentation the way to send my image data (name of field, sending mode...?).

require('OAuth2/Client.php');
require('OAuth2/GrantType/IGrantType.php');
require('OAuth2/GrantType/AuthorizationCode.php');

const CLIENT_ID     = 'XXX';
const CLIENT_SECRET = 'XX';

const REDIRECT_URI           = 'http://127.0.0.1/test_api_wp/test.php';

const AUTHORIZATION_ENDPOINT = 'http://wordpress.local/oauth/authorize';
const TOKEN_ENDPOINT         = 'http://wordpress.local/oauth/token';

$client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);

if (!isset($_GET['code']))
{
    $auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI);
    header('Location: ' . $auth_url);
    die('Redirect');
}
else
{
    $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
    $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params); //authorization_code
    $token = $response['result']['access_token'];
    $client->setAccessToken($token);
    $client->setAccessTokenType(OAuth2\Client::ACCESS_TOKEN_BEARER);

}

$values = array(
    "date" => "2015-11-26 10:00:00",
    "date_gmt" => "2015-11-26 09:00:00",
    "modified" => "2015-11-26 10:00:00",
    "modified_gmt" => "2015-11-26 09:00:00",
    "status" => "future",
    "title" => "Titre media",       
    "description" => "description media",
    "media_type" => "image",
    "source_url" => "https://www.base64-image.de/build/img/mr-base64-482fa1f767.png"
);

$data = $client->fetch("wordpress.local/wp-json/wp/v2/media", $values, "POST");
echo "<pre>";print_r($data);echo "</pre>";

The response :

Array
(
    [result] => Array
        (
            [code] => rest_upload_no_data
            [message] => No data supplied
            [data] => Array
                (
                    [status] => 400
                )

        )

    [code] => 400
    [content_type] => application/json; charset=UTF-8
)

Any idea? Thanks a lot

6
  • I've added the coded from your comment to the question. Remember that you can edit the question at any time to add more information or make it more clear.
    – cybmeta
    Nov 26, 2015 at 9:30
  • The extra ; in wordpress.local/wp-json/wp/v2/media";is a mistype here or it is in your real code too?
    – cybmeta
    Nov 26, 2015 at 9:33
  • According with docs, WP REST API v2 requires this OAuth plugin. I don't know if the library that you are using (OAuth2/Client.php) is compatible with WP REST API or not, but it is probably not.
    – cybmeta
    Nov 26, 2015 at 9:45
  • Thanks a lot !The extra --> ; is not present in my real code! I use official OAuth plugin to authenticate me, files OAuth2.Client.php is only library to make curl requests easily
    – kain34440
    Nov 26, 2015 at 9:51
  • There is a Create a Media section in (documentation)[v2.wp-api.org/reference/media/]. I think your source_url should be inside post object.
    – ville6000
    Nov 26, 2015 at 11:09

3 Answers 3

11

SO! This is fun.

Keep in mind the WP-API is still very, very much a work-in-progress.

Content-Disposition

I found an issue reported on the WP-API issue queue about Content-Disposition. This is a required header for posting new media content and there are some very, very strict requirements when it comes to providing this in the proper format.

The Purpose of Create Media Endpoint

First, Let's take a step back. The API assumes at this point you have already uploaded a new file to the correct directory. This endpoint is creating the media content in the database that references this file.

The solution

You have to specify the filename of the media file to associate to your new content. This cannot be a remote url. As you can see from the v2 documentation, source_url and link are read-only. All you have to do to successfully submit your new content is add the following to your header:

'Content-Disposition' => 'filename=name-of-file.jpg',

As mentioned in the ticket, you cannot add quotes or specify the method you're using to send the file. It must be in the format above. At least, this is the case until they change it all around.

Make sure the file type is one of the accepted file types and you're including the extension of the file is included in the request. Thanks to Dr Deo in the comments.

For the record, I laughed with giddy joy when I finally figured this one out... scared the hell out of my wife.

4
  • 1
    Big thx for the hint with the Content-Disposition !
    – pHiL
    Jul 19, 2016 at 23:01
  • 1
    I think this answer is only a hint, and not a complete solution. I am following this advice and i obtain the error Sorry, this file type is not permitted for security reasons
    – Brethlosze
    Jan 16, 2019 at 13:44
  • @Brethlosze That sounds like an unrelated issue. WordPress blocks certain types of media in the normal upload process. Jan 17, 2019 at 15:38
  • 3
    @Brethlosze the file extension needs to be one of the accepted types. For example this works curl --request POST --url http://localhost/kayinjaproject/wp-json/wp/v2/media --header "cache-control: no-cache" --header "content-disposition: attachment; filename=tmp.png" --header "authorization: Basic cm9vdDppYW1haGVybw==" --header "content-type: image/png" --data-binary "@c:/gnu/png.png" --location but if you omit the png from the filename tmp.png, you get error sorry, this file type is not permitted for security reasons
    – Dr Deo
    Feb 1, 2019 at 11:41
2

For the sake of "cross-referencing", see my related answer here on StackOverflow about media upload and using that media as "featured media" for a post.

0

The answer for PHP CURL:

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'EndPoint',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array('file'=> new CURLFILE('LocalFilePathHere')),
  CURLOPT_HTTPHEADER => array(
    'Content-Disposition: attachment; filename=abc.jpg',
    'Content-Type: image/jpeg',
    'Authorization: XXX YYY'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

If you still face issue "Sorry, this file type is not permitted for security reasons", you have to add to wp-config.php to disable Fiter for Admin User

define('ALLOW_UNFILTERED_UPLOADS', true);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.