У меня есть плагин TinyMCE, который генерирует изображения PNG с использованием HTMLCanvasElement.toDataURL()
( MDN ). В настоящее время я просто отображаю их в бэкэнде, помещая data-URI в тег изображения, но я бы очень хотел добавить их в библиотеку мультимедиа WordPress.
Каков наилучший (то есть VIP-совместимый) способ загрузки изображений, которые в настоящее время сериализуются в виде URI-данных в кодировке base64?
Вот моя функция загрузки:
<?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();
}
}
Это как я использую WP_Filesystem
и wp_insert_attachment()
исправляю? Или я должен найти способ использовать media_handle_upload()
вместо этого?
Спасибо!
plugin-development
ajax
uploads
media
aendrew
источник
источник
media_handle_upload()
Требуется идентификатор записи, а его «другу»wp_handle_upload()
требуется, чтобы в$_FILES
массиве был файл , поэтому я действительно считаю, что он не соответствует вашим потребностям. ИМХО, вы можете использовать свой текущий подход, вероятно, я бы использовалwp_upload_bits
вместо того, чтобы иметь дело с файловой системой WP. Более того,wpcom_vip_file_get_contents
сделайте ваш код доступным только в VIP-конкурсе, если вам нужно более общее подходить к стандартуfile_get_contents
, и если вам нужно кешировать, то переходный процесс должен сработать.wp_upload_bits
- это супер полезно. Спасибо!Ответы:
В предыдущем плагине tinymce, который я сделал - я настроил пользовательский транспорт ajax, чтобы я мог просто использовать большой двоичный объект прямо из образа src удаленного img вместо base64 для атрибута данных, а затем использовал REST API для загрузки изображения в медиа библиотека в JS.
Base64 будет примерно на 35% больше, чем BLOB-объекты, поэтому, если имеется много диаграмм или выгрузок, это поможет значительно снизить пропускную способность выгрузки, даже с одним img, следует учитывать производительность, поскольку многие пользователи склонны иметь тонна плагинов установлена. Вы, наверное, уже знаете, насколько ресурсоемким может быть только редактор и tinymce.
Кроме того, в целом я ненавижу выход из JS в PHP, когда в этом нет необходимости: P
Поскольку у вас уже есть набор данных в base64 - вы могли бы использовать простой конвертер - есть много всего, что я только что скопировал и вставил один, который я нашел для примера ниже. https://www.npmjs.com/package/base64toblob отлично работает, если вы хотите, чтобы что-то быстро интегрировалось в вашу сборку.
Вот быстрый рабочий пример, использующий данные base64 изображения заполнителя, я просто добавил его в тему для тестирования, но вы можете использовать его где угодно:
Тема / functions.php:
тема / JS / JS-плагин-name.js:
Файл будет увеличен на -1, -2 автоматически, как обычно, поэтому вы не перезаписываете что-либо, а ответ будет содержать объект мультимедиа с тем, что вам нужно.
некоторые из полезных параметров в ответ:
Если вы конвертировали в base64, то вы также можете просто написать собственный jjery ajax-транспорт и получить img src и пропустить выполнение всего base64-декодирования для объектов BLOB-объектов, что также должно способствовать снижению производительности при кодировании только для декодирования и т. Д.
РЕДАКТИРОВАТЬ:
Я забыл упомянуть: REST API доступен для любого vip-сайта, так что все должно быть в порядке. Я предполагаю, что вы генерируете диаграммы в редакторе tinymce на внутренней стороне - так что пользователь уже аутентифицирован. Приведенный выше пример просто передает одноразовый номер через заголовки в запросе ajax, что является требованием для безопасности в vip.
Вы можете обратиться к документации для соответствия здесь: https://vip.wordpress.com/documentation/api/
Также я не заметил, что вы используете HTMLCanvasElement.toDataURL ()! - Вы можете просто пропустить декодирование b64 и получить двоичный объект напрямую, поскольку вы не извлекаете изображение с пульта и не пытаетесь добавить его и использовать HTMLCanvasElement.toBlob () ( MDN )
источник