$ HTTP_RAW_POST_DATA и Wordpress media_handle_upload - PullRequest
1 голос
/ 12 марта 2011

Итак, я делаю что-то, для чего пользователям нужно загружать изображения из элемента canvas (в интерфейсе) с помощью встроенного в Wordpress API Media Upload API.

Я успешно загрузил изображения с помощью API из файла, введенного в форму:

<input type="file" name="async-upload" id="async-upload" size="40" />
...
<?php $new_attach_id = media_handle_upload( 'async-upload', $new_id ); ?>

, и я сохранил изображения с холста, используя свой собственный скрипт:

<script type="text/javascript">
...
var img = canvas.toDataURL("image/png");
...
ajax.send(img );
</script>
...
<?php 
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( 'saved_images/canv_save_test.png', 'wb' );
fwrite( $fp, $unencodedData);
...
?>

Проблема в том, что WordPress media_handle_upload () принимает только индекс к массиву $ _FILES для загрузки.

Итак, вопрос: как я могу передать в него данные изображения из HTTP_RAW_POST_DATA?Могу ли я как-то указать $ _FILES ['tmp-name'] на это?Могу ли я использовать другой сценарий как промежуточный шаг?Могу ли я отпустить обезьян на пишущей машинке, пока они не придумают ответ?

Любая помощь очень, очень ценится!

Спасибо, Кейн

РЕДАКТИРОВАТЬ: Решено

Спасибо @alex за его предложение file_put_contents и ответы на другой связанный с этим вопрос, который я опубликовал здесь Теперь у меня есть эта работа.Решение. Отправьте неизмененные данные изображения base64 в запросе HTTP, перезапишите файл tmp_file, сгенерированный PHP, и отключите некоторые проверки безопасности для WP.Не знаю, насколько это безопасно, но вот код для тех, у кого такая же проблема:

<script type="text/javascript">
$('#save').click(function() {

        // get image data from cavas
        var img = canvas.toDataURL("image/png");

        // open ajax request
        var ajax = new XMLHttpRequest();
        ajax.open("POST",script_url,false); 
        //ajax.open("POST","/dumpvars.php",false); // testing

        // set headers
        boundary_str = "AJAX-------------" + (new Date).getTime();
        ajax.setRequestHeader('Content-Type', "multipart/form-data; boundary=" + boundary_str);

        // callback for completed request
        ajax.onreadystatechange=function()
        {
            if (ajax.readyState == 4)
            { 
                // Write out the filename.
                $("#ajax_out").html("Response: "+ajax.responseText+" End Response");
            }
        }

        // BUILD REQUEST
        var boundary = '--' + boundary_str; 
        var request_body = boundary + '\n'
        // print all html form fields
        $('#save_form input').each(function(){ 
            request_body += 'Content-Disposition: form-data; name="' 
            + $(this).attr('name') + '"' + '\n' 
            + '\n' 
            + $(this).val() + '\n' 
            + '\n' 
            + boundary + '\n';
        });
        // make filename
        var filename = $('#save_form input[name="title"]').val();
        filename = filename.replace(/\s+/g, '-').toLowerCase(); // hyphenate + lowercase
        filename = encodeURIComponent(filename) + (new Date).getTime() + ".png";
        // add image
        request_body += 'Content-Disposition: form-data; name="async-upload"; filename="' 
            + filename + '"' + '\n'
        + 'Content-Type: image/png' + '\n' 
        + '\n' 
        + img
        + '\n' 
        + boundary;

        // Send request
        ajax.send(request_body);

    });
</script>

...


<?php
    // Get transmitted image data 
    $loc = $_FILES['async-upload']['tmp_name'];
    $file = fopen($loc, 'rb');
    $contents = fread($file, filesize($loc));
    fclose($file);
    // Decode image data
    $filteredData=substr($contents, strpos($contents, ",")+1);
    $unencodedData=base64_decode($filteredData);
    // Overwrite temp file
    file_put_contents($loc, $unencodedData);

    // Pass image data to WP Upload (attach to post)
    $override['test_upload'] = false; // Override WP's upload security test (rewriting tmp_name made it fail)
    $override['test_form'] = false;
    $new_attach_id = media_handle_upload( 'async-upload', $new_id, array() , $override );

?>

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Вы можете file_put_contents() данные где-нибудь, а затем создать свой собственный искусственный $_FILES массив, чтобы обмануть функцию WordPress.

0 голосов
/ 23 марта 2014

Я собираюсь обновить этот пост, рассказав о том, как я это делал, на тот случай, если кто-то еще пытается сохранить данные Canvas в Wordpress в качестве вложения в сообщение.

Вместо использования media_handle_upload, где вы должны использовать массив $ _FILES, я использовал функцию media_sideload_image. Чтобы сделать это, все, что вам нужно сделать, это просто сохранить изображение холста в папке на вашем сервере, а затем передать этот URL-адрес media_sideload_image, а также идентификатор записи и все. Он прикрепит этот файл к вашему сообщению и скопирует изображение в папку загрузки. Вы можете создать папку TEMP_UPLOADS на своем сервере, чтобы сохранить загруженный файл, а затем успешно прикрепить его к сообщению, удалив его вручную.

define('UPLOAD_DIR', 'path/to/termp-folder/');
$img = $_POST['img'];
$post_id = $_POST['postId'];
$post_id = (int) $post_id;
$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.jpg';
$success = file_put_contents($file, $data);
$fullURL = $file;
$val = media_sideload_image($fullURL, $post_id, 'none');
echo $val;

Приведенный выше пример не удаляет старый временный файл, но вы можете легко понять, как это сделать. Я чувствую, что это решение намного проще и отлично работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...