Я сделал приложение с помощью 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';
}
}






Прежде всего вы должны очистить свой объект Media, потому что он смешивает общедоступные и частные свойства и имеет слишком много логики. Лучшая практика:
Затем, чтобы ваша форма вызывала ошибки, вам необходимо добавить аннотации утверждений к своей сущности: пример:
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