使用 Symfony 编辑实体中的文件名

Edit file name in entity with Symfony

你好(对不起我的英语,不太自信)

我实际上正在开发一个显示一些眼镜信息的 Symfony 网站。 现在,我需要在创建其中一个时添加图像。在 this 教程的帮助下,我设法做到了这一点。

它基本上是这样工作的:我将图像上传到站点目录,然后将文件名发送到实体 (存储在 MySQL 数据库中)。然后我可以在眼镜的细节中显示图像。

当我要编辑奇观时出现问题。我无法更新图像的名称。我只有两种可能性:1/不编辑实体,或 2/更改图像名称,然后随机获得一个我无法再显示的图像 (这些名称通常类似于 /tmp/phpWb8kwV)

我的图像在实体中是这样实例化的 (in Spectacle.php):

/**
* @var string
*
* @ORM\Column(name="image", type="string", length=255)
* @Assert\NotBlank(message="Veuillez ajouter une image à votre spectacle.")
* @Assert\File(mimeTypes={ "image/png" })
*/
private $image;

眼镜形状的 FormType 是这样制作的 (in SpectacleType.php):

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nom')
            ->add('lieu')
            ->add('dateSpectacle', null, array(
                'label' => 'Date du spectacle',
            ))
            ->add('annee')
            ->add('image',FileType::class, array(
                'label' => 'Image du spectacle',
                'required' => false, //(Still need to provide a file to finalize the creation/edit)
            ));
}

访问这个页面的控制器是这样的(in SpectacleController.php):

/**
 * Creates a new spectacle entity.
 *
 * @Route("/new", name="admin_spectacle_new")
 * @Method({"GET", "POST"})
 */
public function newAction(Request $request)
{
    $spectacle = new Spectacle();
    $form = $this->createForm('FabopBundle\Form\SpectacleType', $spectacle);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();
//--------------------------------------------------------------------
        $file = $spectacle->getImage();            
        $fileName = (md5(uniqid())).'.'.$file->guessExtension();            
        // moves the file to the directory where image are stored
        $file->move(
            $this->getParameter('img_directory'), //(Define in the service.yml)
            $fileName
        );
        $spectacle->setImage($fileName); //(Don't know how to handle file names without this line)
//---------------------------------------------------------------------
        $em->persist($spectacle);
        $em->flush();
        return $this->redirectToRoute('admin_spectacle_show', array('id' => $spectacle->getId()));
    }

    return $this->render('spectacle/new.html.twig', array(
        'spectacle' => $spectacle,
        'form' => $form->createView(),
    ));
}

路由到编辑视图的功能大致相同,但我不能使用

$spectacle->setImage($fileName);

有两种可能性可以解决这个问题:我希望能够更新实体中的新文件名(使用其他信息)或者能够在不更改文件名的情况下更新实体。

我希望我已经足够清楚地解释我的问题... 预先感谢您的回复。

我在尝试上传 PDF/TEXT.. 文件时遇到了这个问题。 但是对于管理图像,我建议您使用 ComurImageBundle,它对您有很大帮助,您的问题将得到解决。 非常简单,您可以按照 link 中的说明下载捆绑包。 然后你像这样修改你的代码: 1/ 在 Spectacle.php 中实例化您的图像(您的图像像字符串一样存储在数据库中)

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

2/ 更新你的基地(php bin/console doctrine:schema:update --force)

3/ 将这些功能添加到您的 Spectacle.php 更新您的数据库模式后,这些功能让您可以在特定目录下上传和存储图像 (web/uploads/spectacles) 不要忘记添加这两个库

use Symfony\Component\HttpFoundation\File\UploadedFile;

use Symfony\Component\Validator\Constraints as Assert;

  /**
 * @Assert\File()
 */
private $file;

/**
 * Sets file.
 *
 * @param UploadedFile $file
 */
public function setFile(UploadedFile $file = null)
{
    $this->file = $file;
}

/**
 * Get file.
 *
 * @return UploadedFile
 */
public function getFile()
{
    return $this->file;
}

/**
 * @ORM\PrePersist
 */
public function preUpload()
{
    if (null !== $this->file) {
        $this->image = uniqid() . '.' . $this->file->guessExtension();
    }
}

/**
 * @ORM\PostPersist
 */
public function upload()
{
    if (null === $this->file) {
        return;
    }

    // If there is an error when moving the file, an exception will
    // be automatically thrown by move(). This will properly prevent
    // the entity from being persisted to the database on error
    $this->file->move($this->getUploadRootDir(), $this->image);
}

public function getUploadDir()
{
    return 'uploads/spectacles';
}

public function getBaseUrl()
{
    $currentPath = $_SERVER['PHP_SELF'];

    $pathInfo = pathinfo($currentPath);

    return substr($pathInfo['dirname']."/", 1);
}

public function getUploadRootDir()
{
    return $this->getBaseUrl() . $this->getUploadDir();
}

public function getWebPath()
{
    return null === $this->image ? null : $this->getUploadDir() . '/' . $this->image;
}

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

4/ 像这样修改 FormType (SpectacleType.php)

use Comur\ImageBundle\Form\Type\CroppableImageType;

  public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nom')
            ->add('lieu')
            ->add('dateSpectacle', null, array(
                'label' => 'Date du spectacle',
            ))
            ->add('annee')
            ->add('image', CroppableImageType::class, array('label' => 'Image', 'required' => true,
            'uploadConfig' => array(
                'uploadUrl' => $myEntity->getUploadDir(),       // required - see explanation below (you can also put just a dir path)
                'webDir' => $myEntity->getUploadRootDir(),              // required - see explanation below (you can also put just a dir path)
                'fileExt' => '*.png',  // required - see explanation below (you can also put just a dir path)
                'showLibrary' => false,
            ),
            'cropConfig' => array(
                'minWidth' => 128,
                'minHeight' => 128,
                'aspectRatio' => true,
            )
        ));    
}

5/ 从您的控制器中删除所有这些您不需要的行

//--------------------------------------------------------------------
        $file = $spectacle->getImage();            
        $fileName = (md5(uniqid())).'.'.$file->guessExtension();            
        // moves the file to the directory where image are stored
        $file->move(
            $this->getParameter('img_directory'), //(Define in the service.yml)
            $fileName
        );
        $spectacle->setImage($fileName); //(Don't know how to handle file names without this line)
//---------------------------------------------------------------------

6/就这样你可以在new.html.twig和edit.html.twig中调用你的图像形式,一切都会好起来的,请尝试并通知有问题找我

解决方案很愚蠢...

事实上,访问 edit 路由的控制器没有那些行:

$em = $this->getDoctrine()->getManager();
...
$em->persist($spectacle);
$em->flush();

我需要尽快完成它。如果我以后有更多时间,我会尝试让它与 ComurImageBundle 一起工作。

谢谢你的帮助,下次我会小心的...