Eu tenho um plugin TinyMCE que gera imagens PNG usando HTMLCanvasElement.toDataURL()
( MDN ). Atualmente, estou apenas exibindo-os no back-end, colocando o URI de dados em uma tag de imagem, mas eu realmente gostaria de adicioná-los à Biblioteca de mídia do WordPress.
Qual é a melhor maneira (ou seja, compatível com VIP) de enviar imagens atualmente serializadas como um URI de dados codificado em base64?
Aqui está a minha função de upload até agora:
<?php
/**
* AJAX callback that inserts chart as attachment into the WP database
*/
public static function insert_axis_attachment() {
// Get config
$axis_config = json_decode( $_POST['axisConfig'] );
if ( ! isset( $_POST['axisJS_nonce'] )
|| ! wp_verify_nonce( $_POST['axisJS_nonce'] )
|| ! current_user_can( 'upload_files' )
|| ! current_user_can( 'edit_post', $_POST['post_id'] )
|| ( isset( $axis_config->ID ) && ! current_user_can( 'edit_post', $axis_config->ID ) )
) {
return false;
}
// Begin saving PNG to filesystem
if ( false === ( $creds = request_filesystem_credentials( 'admin-ajax.php', '', false, false, null ) ) ) {
return false; // stop processing here
}
if ( ! WP_Filesystem( $creds ) ) {
request_filesystem_credentials( 'admin-ajax.php', '', true, false, null );
return false;
}
global $wp_filesystem;
$upload_dir = wp_upload_dir();
$chart_filename = sanitize_title_with_dashes( $axis_config->chartTitle ) . '_' . time() . '.png';
$filename = trailingslashit( $upload_dir['path'] ) . $chart_filename;
$uriPhp = 'data://' . substr( $_POST['axisChart'], 5 ); // Via http://stackoverflow.com/questions/6735414/php-data-uri-to-file/6735458#6735458
$binary = wpcom_vip_file_get_contents( $uriPhp );
$wp_filesystem->put_contents(
$filename,
$binary,
FS_CHMOD_FILE // predefined mode settings for WP files
);
// Insert or update attachment.
if ( ! $axis_config->ID ) {
$attachment = array(
'guid' => $upload_dir['url'] . '/' . basename( $filename ),
'post_title' => $axis_config->chartTitle,
'post_content' => '', // Must be empty string
'post_status' => 'published',
'post_mime_type' => 'image/png',
'post_status' => 'inherit',
);
$attach_id = wp_insert_attachment( $attachment, $filename, $_POST['post_id'] );
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
update_post_meta( $attach_id, '_axisWP', $axis_config );
echo esc_attr( $attach_id );
die();
} else {
update_attached_file( $axis_config->ID, $filename );
update_post_meta( $axis_config->ID, '_axisWP', $axis_config );
echo esc_attr( $axis_config->ID );
die();
}
}
É como estou usando WP_Filesystem
e wp_insert_attachment()
correto? Ou devo encontrar uma maneira de usar media_handle_upload()
?
Obrigado!
plugin-development
ajax
uploads
media
aendrew
fonte
fonte
media_handle_upload()
exigem um ID de postagem, e seu "amigo"wp_handle_upload()
exige que um arquivo exista na$_FILES
matriz, por isso acho que eles não atendem às suas necessidades. IMHO, você pode usar sua abordagem atual, provavelmente eu teria usado emwp_upload_bits
vez de lidar com o sistema de arquivos WP. Além disso,wpcom_vip_file_get_contents
disponibilize seu código apenas no concurso VIP, se você precisar de uma apelação mais geral, um padrãofile_get_contents
deve ser bom e, se precisar armazenar em cache, um transitório deve fazer o truque.wp_upload_bits
- isso é super útil. Obrigado!Respostas:
Em um plug-in tinymce anterior que eu criei - configurei um transporte ajax personalizado para poder usar o blob diretamente da imagem src de um img remoto em vez de base64 em um atributo de dados e, em seguida, usei a API REST para carregar a imagem a biblioteca de mídia em js.
O Base64 será cerca de 35% maior que um blob, portanto, se houver muitos gráficos ou uploads, isso ajudará a reduzir bastante a largura de banda do upload, mesmo com apenas um único img, o desempenho deve ser considerado, pois muitos usuários tendem a ter uma tonelada de plugins instalados. Você provavelmente já sabe o quão intensivo em recursos, apenas o editor e o tempo podem ser, em primeiro lugar.
Além disso, no geral, eu odeio quebrar o JS para o PHP quando não é 100% necessário: P
Como você já possui os dados definidos no base64 - você pode usar um conversor simples - existem muitos por aí, apenas copiei e colei um que encontrei no exemplo abaixo. https://www.npmjs.com/package/base64toblob funciona bem se você quiser algo rápido para integrar à sua compilação.
Aqui está um exemplo de trabalho rápido usando dados de uma imagem de espaço reservado na base64, acabei de lançar um tema para teste, mas você pode usá-lo onde quiser:
theme / functions.php:
theme / js / js-plugin-name.js:
O arquivo será incrementado -1, -2 automaticamente como o normal, para que você não substitua o material yadda yadda, e a resposta conterá o objeto de mídia com o que você precisar.
alguns dos parâmetros úteis em resposta:
Se você se converteu em base64, também pode escrever um transporte jquery ajax personalizado e pegar o img src e pular toda a decodificação de base64 para coisas de blob também, além de ajudar a obter resultados de codificação apenas para decodificar, etc.
EDITAR:
Esqueci de mencionar: a API REST está disponível para qualquer site vip, portanto, isso deve ser bom. Suponho que você esteja gerando os gráficos no editor de tim-tim no back-end - para que o usuário já esteja autenticado. O exemplo acima está apenas passando o nonce entre os cabeçalhos em uma solicitação ajax, que é um requisito de segurança no vip.
Você pode consultar a documentação para conformidade aqui: https://vip.wordpress.com/documentation/api/
Também não notei que você estava usando HTMLCanvasElement.toDataURL ()! - Você pode pular a decodificação de b64 e obter o blob diretamente, pois não está buscando a imagem de um controle remoto e tentando adicioná-la e usar HTMLCanvasElement.toBlob () ( MDN )
fonte