Añadir medios con WP-Rest-API v2

26 nov 2015, 10:18:46
Vistas: 33.6K
Votos: 12

Necesito ayuda para subir una imagen de medios en mi blog de WordPress a través de la WP-REST-API v2 y autenticación OAuth2.

No encontré en la documentación de la API REST la forma de enviar los datos de mi imagen (nombre del campo, modo de envío...?).

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('Redireccionar');
}
else
{
    $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
    $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params); // código_de_autorización
    $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" => "Título del medio",       
    "description" => "descripción del medio",
    "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>";

La respuesta:

Array
(
    [result] => Array
        (
            [code] => rest_upload_no_data
            [message] => No se suministraron datos
            [data] => Array
                (
                    [status] => 400
                )

        )

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

¿Alguna idea? Muchas gracias

6
Comentarios

He añadido el código de tu comentario a la pregunta. Recuerda que puedes editar la pregunta en cualquier momento para agregar más información o hacerla más clara.

cybmeta cybmeta
26 nov 2015 11:30:20

El ; adicional en wordpress.local/wp-json/wp/v2/media"; ¿es un error de tipeo aquí o también está en tu código real?

cybmeta cybmeta
26 nov 2015 11:33:11

De acuerdo con la documentación, WP REST API v2 requiere este plugin OAuth. No sé si la biblioteca que estás usando (OAuth2/Client.php) es compatible con WP REST API o no, pero probablemente no lo sea.

cybmeta cybmeta
26 nov 2015 11:45:29

¡Muchas gracias! El extra --> ; no está presente en mi código real. Uso el plugin oficial de OAuth para autenticarme, el archivo OAuth2.Client.php es solo una librería para hacer solicitudes curl más fácilmente

kain34440 kain34440
26 nov 2015 11:51:43

Hay una sección de Crear un Media en la (documentación)[http://v2.wp-api.org/reference/media/]. Creo que tu source_url debería estar dentro del objeto post.

ville6000 ville6000
26 nov 2015 13:09:59

Hola ville6000, ¿puedes explicar tu comentario?

kain34440 kain34440
26 nov 2015 16:32:40
Mostrar los 1 comentarios restantes
Todas las respuestas a la pregunta 3
4
11

¡VAYA! Esto es divertido.

Ten en cuenta que la WP-API sigue siendo un trabajo muy, muy en progreso.

Content-Disposition

Encontré un problema reportado en la cola de issues de WP-API sobre Content-Disposition. Este es un encabezado requerido para publicar nuevo contenido multimedia y hay requisitos muy, muy estrictos en cuanto al formato correcto para proporcionarlo.

El Propósito del Endpoint Create Media

Primero, retrocedamos un paso. La API asume en este punto que ya has subido un nuevo archivo al directorio correcto. Este endpoint está creando el contenido multimedia en la base de datos que referencia este archivo.

La solución

Tienes que especificar el nombre del archivo multimedia para asociarlo a tu nuevo contenido. Esto no puede ser una URL remota. Como puedes ver en la documentación v2, source_url y link son de solo lectura. Todo lo que tienes que hacer para enviar con éxito tu nuevo contenido es agregar lo siguiente a tu encabezado:

'Content-Disposition' => 'filename=nombre-del-archivo.jpg',

Como se menciona en el ticket, no puedes agregar comillas ni especificar el método que estás usando para enviar el archivo. Debe estar en el formato anterior. Al menos, este es el caso hasta que lo cambien todo.

Asegúrate de que el tipo de archivo sea uno de los tipos de archivo aceptados y que incluyas la extensión del archivo en la solicitud. Gracias a Dr Deo en los comentarios.

Para que conste, me reí con alegría desbordante cuando finalmente resolví esto... asusté a mi esposa de lo lindo.

14 feb 2016 06:03:32
Comentarios

¡Muchas gracias por el consejo con el Content-Disposition!

pHiL pHiL
20 jul 2016 02:01:34

Creo que esta respuesta es solo una pista y no una solución completa. Estoy siguiendo este consejo y obtengo el error Lo sentimos, este tipo de archivo no está permitido por razones de seguridad

Brethlosze Brethlosze
16 ene 2019 15:44:58

@Brethlosze Eso suena como un problema no relacionado. WordPress bloquea ciertos tipos de archivos en el proceso normal de carga.

MikeNGarrett MikeNGarrett
17 ene 2019 17:38:20

@Brethlosze la extensión del archivo debe ser uno de los tipos aceptados. Por ejemplo, esto funciona 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 pero si omites la extensión png del nombre de archivo tmp.png, obtendrás error sorry, this file type is not permitted for security reasons

Dr Deo Dr Deo
1 feb 2019 13:41:28
0

Para efectos de "referencia cruzada", consulta mi respuesta relacionada aquí en StackOverflow sobre la carga de medios y el uso de ese medio como "medio destacado" para una publicación.

20 jul 2016 02:01:13
0

La respuesta para 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('RutaDelArchivoLocalAquí')),
  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;

Si aún enfrentas el problema "Lo sentimos, este tipo de archivo no está permitido por razones de seguridad", debes agregar a wp-config.php para desactivar el filtro para el usuario administrador:

define('ALLOW_UNFILTERED_UPLOADS', true);
13 abr 2021 13:32:22