Añadir medios con WP-Rest-API v2
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
¡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.

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 Eso suena como un problema no relacionado. WordPress bloquea ciertos tipos de archivos en el proceso normal de carga.

@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

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.

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);
