Файл (изображение) не обновляется

Я сделал приложение с помощью Symfony, и я использую медиа-объект, чтобы разрешить загрузку файлов и связывание их с другими объектами (например, изображение со статьей).

Если я хочу создать новую статью с изображением, все будет работать отлично, но если позже я захочу изменить ту же картинку, это не сработает. Более того, если в то же время я обновлю другое поле, такое как заголовок или что-то еще, я увижу, что все они изменятся, кроме изображения.

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

Мой код: Media.php

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* Media
*
* @ORM\Table("media")
* @ORM\Entity(repositoryClass = "AppBundle\Repository\MediaRepository")
* @ORM\HasLifecycleCallbacks
*/
class Media
{
/**
 * @var integer
 *
 * @ORM\Column(name = "id", type = "integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy = "AUTO")
 */
private $id;

/**
 * @var \DateTime
 *
 * @ORM\COlumn(name = "updated_at",type = "datetime", nullable=true)
 */
private $updateAt;

/**
 * @ORM\PostLoad()
 */
public function postLoad()
{
    $this->updateAt = new \DateTime();
}

/**
 * @ORM\Column(type = "string",length=255, nullable=true)
 */
public $path;

public $file;

public function getUploadRootDir()
{
    return realpath(__dir__.'/../../../web/img/upload');
}

public function getAbsolutePath()
{
    return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
}

public function getAssetPath()
{
    return 'img/upload/'.$this->path;
}

/**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{
    $this->tempFile = $this->getAbsolutePath();
    $this->oldFile = $this->getPath();
    $this->updateAt = new \DateTime();

    if (null !== $this->file) {
        $this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
    }
}

/**
 * @ORM\PostPersist()
 * @ORM\PostUpdate()
 */
public function upload()
{
    $extentions_allowed = array('jpeg', 'png', 'svg', 'gif');

    if (null !== $this->file) {
        if (in_array($this->file->guessExtension(), $extentions_allowed))
        {
            $this->file->move($this->getUploadRootDir(), $this->path);
            unset($this->file);
            if ($this->oldFile != null) unlink($this->tempFile);

        }else {
            unset($this->file);
            throw new \Exception('Seules les images sont autorisées (jpg/png/gif/svg)');
        }
    }
}

/**
 * @ORM\PreRemove()
 */
public function preRemoveUpload()
{
    $this->tempFile = $this->getAbsolutePath();
}

/**
 * @ORM\PostRemove()
 */
public function removeUpload()
{
    if (file_exists($this->tempFile)){
        unlink($this->tempFile);
    }
}

/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this->id;
}

public function getPath()
{
    return $this->path;
}

}

Контроллер, который обновляет объект (например, статья)

public function blocAction(Request $request, Bloc $bloc = null){

    if ($bloc){
        $form = $this->createForm('AppBundle\Form\BlocType', $bloc, array(
            'type' => $bloc->getType()
        ));
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid() ){
                try{
                    $this->getDoctrine()->getManager()->persist($bloc);
                    $this->getDoctrine()->getManager()->flush();
                }catch (\Exception $e){
                    $this->addFlash(
                        'error',
                        $e->getMessage()
                    );
                }

            return $this->redirectToRoute('app_admin_bloc', array('id' => $bloc->getId()));
        }

        return $this->render('admin/bloc.html.twig', array(
            'bloc' => $bloc,
            'form' => $form->createView()
        ));
    }else{
       return $this->redirectToRoute('app_admin_index');
    }


}

Форма юридического лица

<?php
namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;


class MediaType extends AbstractType
{
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('file',FileType::class, array(
            'attr' => array(
                'class' => 'image-preview'
            )
        ));
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Media'
    ));
}

/**
 * {@inheritdoc}
 */
public function getBlockPrefix()
{
    return 'app_bundle_media';
}
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
66
1

Ответы 1

Прежде всего вы должны очистить свой объект Media, потому что он смешивает общедоступные и частные свойства и имеет слишком много логики. Лучшая практика:

  • установить все ваши свойства как частные и получить к ним доступ с помощью методов getter / setter;
  • в идеале поместите свою логику загрузки в службу, которая делает только это.

Затем, чтобы ваша форма вызывала ошибки, вам необходимо добавить аннотации утверждений к своей сущности: пример:

use Symfony\Component\Validator\Constraints as Assert;

class Media
{
    //...

    /**
     * @ORM\Column(type = "string",length=255, nullable=true)
     */
    private $path;

     /**
     * @Assert\NotBlank()
     * @Assert\File(
     *     mimeTypes = {"image/jpeg", "image/png", "application/svg+xml", "image/gif"},
     *     message = "Seules les images sont autorisées (jpg/png/gif/svg)"
     * )
     */
    private $file;

    //...

Таким образом вы избавитесь от текущего чека $extentions_allowed.

Взгляните на этот подробный документ о том, как правильно загрузить файл: https://symfony.com/doc/current/controller/upload_file.html

Другие вопросы по теме