Salvando o URI de dados na biblioteca de mídia

9

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_Filesysteme wp_insert_attachment()correto? Ou devo encontrar uma maneira de usar media_handle_upload()?

Obrigado!

aendrew
fonte
Não tenho certeza se este é um bom lugar para perguntar no contexto da conformidade VIP. Existem muito poucas perguntas aqui e não estou confiante de que tenhamos pessoas com conhecimentos tão específicos por aí. : \
Rarst
11
@rarst Nem estou procurando conformidade VIP tanto quanto "Estou usando as classes de manipulação de arquivos do WordPress corretamente", da maneira que os VIPs fazem 12 fatores (ou seja, se alguém tem um "carregamento automático de todas as mídias" imagens da biblioteca para o plug-in Amazon S3 ", ele também funcionará com isso. O texto acima parece funcionar (atualizando com alterações agora), mas não tenho certeza de que ele esteja conectado à Biblioteca de mídia de maneira convencional.
aendrew
11
media_handle_upload()exigem um ID de postagem, e seu "amigo" wp_handle_upload()exige que um arquivo exista na $_FILESmatriz, por isso acho que eles não atendem às suas necessidades. IMHO, você pode usar sua abordagem atual, provavelmente eu teria usado em wp_upload_bitsvez de lidar com o sistema de arquivos WP. Além disso, wpcom_vip_file_get_contentsdisponibilize seu código apenas no concurso VIP, se você precisar de uma apelação mais geral, um padrão file_get_contentsdeve ser bom e, se precisar armazenar em cache, um transitório deve fazer o truque.
gmazzap
@GMI não sabia wp_upload_bits- isso é super útil. Obrigado!
aendrew

Respostas:

1

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:

    add_action( 'wp_enqueue_scripts', 'js_plugin_name_scripts' );

    function js_plugin_name_scripts() {
        wp_register_script( 'js-plugin-name', get_parent_theme_file_uri( 'js/js-plugin-name.js' ), array( 'wp-api' ) );
        wp_localize_script( 'wp-api', 'wpApiSettings', array(
            'root' => esc_url_raw( rest_url() ),
            'nonce' => wp_create_nonce( 'wp_rest' )
        ) );
        wp_enqueue_script( 'js-plugin-name' );
    }

theme / js / js-plugin-name.js:

    // Wait for API load.
    wp.api.loadPromise.done( function() {

        var base64, blob;

        /**
         * Convert base64 data to blob.
         * 
         * @param {string} base64
         * @param {string} mime 
         */
        function base64ToBlob( base64, mime ) {
            mime = mime || '';
            var sliceSize = 1024;
            var byteChars = window.atob( base64 );
            var byteArrays = [];

            for ( var offset = 0, len = byteChars.length; offset < len; offset += sliceSize ) {
                var slice = byteChars.slice( offset, offset + sliceSize );

                var byteNumbers = new Array( slice.length );
                for ( var i = 0; i < slice.length; i++ ) {
                    byteNumbers[i] = slice.charCodeAt(i);
                }

                var byteArray = new Uint8Array( byteNumbers );

                byteArrays.push( byteArray );
            }

            return new Blob(byteArrays, {type: mime});
        }

        base64 = "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";

        blob = base64ToBlob( base64, 'image/png' );

        // Upload to media library.
        jQuery.ajax( {
            url: wpApiSettings.root + 'wp/v2/media',
            method: 'POST',
            beforeSend: function ( xhr ) {
                xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
                xhr.setRequestHeader( 'Content-Disposition', 'attachment;filename=' + 'placeholder.png' );
            },
            data: blob,
            cache: false,
            contentType: false,
            processData: false
        } ).done( function ( response ) {

            // Response contains the media details.
            console.log( response );
        } );
    });

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:

    response.id = post id
    response.source_url = url to file ie http://local.wordpress.dev/wp-content/uploads/2017/07/placeholder.png
    response.title.rendered(or .raw) = media title if needed
    response.slug = media slug
    response.media_details.height = contains the original uploaded img height
    response.media_details.width = contains the original uploaded img width
    response.media_details.sizes = contains the various img sizes generated - ie full/thumb/sm/med/lrg etc --- don't always rely on naming conventions ;)!

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 )

Tim Elsass
fonte
congrats, primeiro uso útil do API REST que provavelmente não é trivial para replicar que eu vejo
Mark Kaplun