VichUploaderBundle & Cropit — передача base64 в экземпляр файла

Во-первых, поскольку английский не является моим родным языком, прошу извинить меня за ошибки.

Я пытаюсь разработать свой первый проект через Symfony2. Однако я застрял с загрузкой файлов. Итак, я установил VichUploaderBundle, который предоставляет именно то, что мне нужно для управления: все виды загруженных медиафайлов (в основном изображения).

Зачем мне нужно загружать изображение? В моем проекте есть пользователь, и он может редактировать свой профиль. Итак, у меня есть объект ProfilePicture, который должен управлять загрузкой благодаря VichUploaderBundle. Он отлично работает, когда форма отправляется с помощью кнопки отправки или с помощью ajax.

Однако, чтобы улучшить взаимодействие с пользователем, я также добавил плагин jQuery (Cropit). Cropit дает base64 обрезанной картинки. Я отправляю все с помощью ajax.

И знаете... я борюсь. Я искал везде в Интернете, чтобы найти кого-то с началом идеи, я прочитал всю документацию, пытаясь найти другой способ сделать то, что я пытаюсь сделать.

Вот мой фактический "тестовый" код:

$base64 = $request->request->get('base64');
preg_match('/data:([^;]*);base64,(.*)/', $base64, $matches);
$data = base64_decode($matches[2]);
$ui = uniqid().'.png';
$file = 'images/profile_pictures/'. $ui;
file_put_contents($file, $data);

$picture = new File($file);

$profile->getPicture()->setImageFile($picture);

Это позволяет мне сохранить обрезанное изображение в нужном каталоге. Однако это не совсем то, чего мне хотелось бы. На самом деле, я просто пытаюсь найти способ преобразовать содержимое base64 в то, что присутствовало бы в $profile->getPicture()->setImageFile(), если бы я только что отправил изображение. Я неточен, и мне жаль. Это первый раз, когда мне нужно создать систему загрузки.

Я подумал, что может быть способ избежать отправки base64. Но что мы можем сделать с такими данными? Можем ли мы использовать jQuery для его декодирования и преобразования моей формы только для отправки формы, как если бы я просто выбрал свое изображение и хотел бы сохранить его целиком?

Как вы справляетесь с этим в своем проекте? Есть ли какой-нибудь другой набор лучше, чем этот? Я искал, безуспешно. SonataMediaBundle кажется большим для моих нужд, и я не нашел способа сохранить с ним обрезанное изображение.

Я нашел кого-то, кто хотел управлять им в Git VichUploaderBundle. Однако его проблема была закрыта до того, как был дан лучший ответ... https://github.com/dustin10/VichUploaderBundle/issues/223

Заранее спасибо за вашу помощь!


person Community    schedule 18.07.2015    source источник


Ответы (2)


Проблема была закрыта, потому что она не вписывается в объем пакета. VichUploaderBundle в основном сопоставляет UploadedFile объекты с сущностями через формы, вот и все.

Ключевые слова для вашей проблемы: «UploadedFile"» и «формы».

Если вам нужно отправить файл в виде строк в кодировке base64, необработанных байтов и т. д., вам придется преобразовать его в UploadedFile, чтобы он работал с VichUploaderBundle. Я предполагаю, что DataTransformer может помочь. Он может декодировать строку в кодировке base64 и сохранять ее во временном файле, который можно использовать для создать объект UploadedFile.

person K-Phoen    schedule 18.07.2015

Я хотел бы поделиться своим текущим решением.

Мне нужно загрузить изображения, закодированные в base64. Эти изображения генерируются с использованием библиотеки cropper.js и отправляются в определенную конечную точку.

Я использовал DataTransformerInterface для создания объекта UploadedFile, как предложил K-Phoen.

Я хотел бы указать на некоторые отличия от канонического использования бандла.

Используйте TextType вместо VichFileType (иначе проверка завершится ошибкой). Используйте преобразователь данных для декодирования изображения и временного сохранения (спасибо за подсказку, K-Phoen).

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('file', TextType::class, ['required' => true]);
    $builder->get('file')->addModelTransformer(new FileToBase64Transformer());
}

My FileToBase64Trasformer:

class FileToBase64Transformer implements DataTransformerInterface
{
    public function transform($value)
    {
    }

    public function reverseTransform($value)
    {
        $tmpFilePath = tempnam(sys_get_temp_dir(), 'allegato_');

        $tmp = fopen($tmpFilePath, 'wb+');

        $matches = [];
        preg_match('/^data:([\w-]+\/[\w-]+);base64,(.+)$/', $value, $matches);

        $size = fwrite($tmp, base64_decode($matches[2]));

        fclose($tmp);

        return new UploadedFile($tmpFilePath, 'originalName', $matches[1], $size, 0, true);
    }
}

Обратите внимание на параметры конструктора UploadedFile:

  1. Третий параметр — тип mime файла.
  2. 4-й параметр - это код ошибки (0 означает отсутствие ошибок вообще)
  3. 5-й параметр делает свое дело. Внутренне UploadedFile вызовет функцию is_uploaded_file, которая завершится ошибкой (файл создан путем декодирования строки base64, а не загружена), что вызовет неизвестную ошибку. Если вы понимаете и принимаете риск, установите для этого параметра значение true, чтобы избежать его.
person Ilario Pierbattista    schedule 15.02.2018