Mam wtyczkę TinyMCE, która generuje obrazy PNG za pomocą HTMLCanvasElement.toDataURL()
( MDN ). Obecnie wyświetlam je tylko na zapleczu, umieszczając identyfikator URI danych w znaczniku obrazu, ale naprawdę chciałbym je dodać do biblioteki multimediów WordPress.
Jaki jest najlepszy (tj. Zgodny z VIP-em) sposób przesyłania obrazów obecnie zserializowanych jako URI zakodowane w formacie base64?
Oto jak dotąd moja funkcja przesyłania:
<?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();
}
}
Czy używam WP_Filesystem
i wp_insert_attachment()
poprawiam? Czy powinienem media_handle_upload()
zamiast tego znaleźć sposób na użycie ?
Dzięki!
plugin-development
ajax
uploads
media
Aendrew
źródło
źródło
media_handle_upload()
wymagają identyfikatora postu, a jego „przyjaciel”wp_handle_upload()
wymaga pliku istniejącego w$_FILES
tablicy, więc naprawdę uważam, że nie odpowiadają twoim potrzebom. IMHO możesz użyć swojego obecnego podejścia, prawdopodobnie użyłbymwp_upload_bits
zamiast zajmować się systemem plików WP. Co więcej,wpcom_vip_file_get_contents
udostępniaj swój kod tylko w konkursie VIP, jeśli potrzebujesz bardziej ogólnego podejścia, standardfile_get_contents
powinien być w porządku, a jeśli potrzebujesz buforować, przejściowy powinien załatwić sprawę.wp_upload_bits
tym - to bardzo pomocne. Dzięki!Odpowiedzi:
W poprzedniej wtyczce tinymce, którą stworzyłem - skonfigurowałem niestandardowy transport ajax, więc mogłem po prostu użyć obiektu blob bezpośrednio z obrazu src zdalnej img zamiast base64 na atrybucie danych, a następnie użyłem interfejsu API REST do przesłania obrazu do biblioteka multimediów w js.
Base64 będzie około 35% większy niż obiekt blob, więc jeśli jest dużo wykresów lub przesyłania, pomoże to nieco zmniejszyć przepustowość przesyłania, nawet przy jednym obrazie, należy wziąć pod uwagę wydajność, ponieważ wielu użytkowników ma tendencję do mnóstwo zainstalowanych wtyczek. Prawdopodobnie już wiesz, jak intensywnie wykorzystują zasoby tylko edytor i tinymce.
Dodatkowo, ogólnie nienawidzę włamania się z JS do PHP, gdy nie jest to w 100% konieczne: P
Ponieważ masz już zestaw danych w base64 - możesz użyć prostego konwertera - istnieje wiele rzeczy, które właśnie skopiowałem i wkleiłem, które znalazłem na poniższym przykładzie. https://www.npmjs.com/package/base64toblob działa dobrze, jeśli chcesz szybko zintegrować z kompilacją.
Oto szybki działający przykład z użyciem zastępczego obrazu base64, po prostu wrzuciłem go do kompozycji do testowania, ale możesz go użyć gdziekolwiek chcesz:
theme / functions.php:
theme / js / js-plugin-name.js:
Plik będzie zwiększany o -1, -2 automatycznie jak normalnie, więc nie nadpisujesz rzeczy yadda yadda, a odpowiedź będzie zawierała obiekt multimedialny z czymkolwiek, czego potrzebujesz.
niektóre przydatne parametry w odpowiedzi:
Jeśli przekonwertowałeś na base64, możesz również napisać niestandardowy transport JQuery ajax i pobrać img src i pominąć wykonywanie dekodowania base64, aby usunąć obiekty blob, i powinno to pomóc w poprawieniu wydajności od kodowania tylko do dekodowania itp.
EDYTOWAĆ:
Zapomniałem wspomnieć: interfejs API REST jest dostępny dla dowolnej witryny VIP, więc powinno być dobrze. Zakładam, że generujesz wykresy w edytorze tinymce na zapleczu - więc użytkownik jest już uwierzytelniony. Powyższy przykład po prostu przekazuje nonce przez nagłówki w żądaniu ajax, co jest wymogiem bezpieczeństwa na vipie.
Możesz zapoznać się z dokumentacją dotyczącą zgodności tutaj: https://vip.wordpress.com/documentation/api/
Nie zauważyłem też, że używasz HTMLCanvasElement.toDataURL ()! - Możesz po prostu pominąć dekodowanie b64 i pobrać obiekt blob bezpośrednio, ponieważ nie pobierasz obrazu ze zdalnego i próbujesz go dodać i użyć HTMLCanvasElement.toBlob () ( MDN )
źródło