我创建了一个具有一对多关系图像实体的demo1实体,并使用vich捆绑包进行上传
Demo1隐私
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Controller\UploadImageAction;
/**
* @ORM\Entity(repositoryClass="App\Repository\Demo1Repository")
* @ApiResource(
* collectionOperations={
* "get",
* "post" ={
*
* "controller"=UploadImageAction::class,
* "defaults"={"_api_receive"=false},
* "denormalization_context"={"groups"={"image"}}
* }
* }
* )
*/
class Demo1
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Image", mappedBy="myfiles")
* @ORM\JoinColumn(nullable=false);
*/
private $files;
public function __construct()
{
$this->files = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection|Image[]
*/
public function getFiles(): Collection
{
return $this->files;
}
public function addFile(Image $file): self
{
if (!$this->files->contains($file)) {
$this->files[] = $file;
$file->setMyfiles($this);
}
return $this;
}
public function removeFile(Image $file): self
{
if ($this->files->contains($file)) {
$this->files->removeElement($file);
// set the owning side to null (unless already changed)
if ($file->getMyfiles() === $this) {
$file->setMyfiles(null);
}
}
return $this;
}
}
图像实体
<?php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Serializer\Annotation\Groups;
use App\Controller\UploadImageAction;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Api\Data\TagInterface;
use App\Api\File\ImageInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="data_files_images")
* @ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* @Vich\Uploadable()
*/
class Image extends AbstractEntity implements ImageInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"get","patch","post"})
*/
private $id;
/**
* @ORM\Column(name="mimetype", type="string", length=20, nullable=true)
*/
private $mimeType;
/**
* @Vich\UploadableField(mapping="images", fileNameProperty="url")
* @Assert\NotNull()
* @Groups({"image"})
*/
private $files;
/**
* @ORM\Column(name="url", type="string", length=255, nullable=true)
* @Groups({"get","patch","post"})
*/
private $url;
/**
* @ORM\Column(name="width", type="integer", nullable=true)
*/
private $width;
/**
* @ORM\Column(name="length", type="integer", nullable=true)
*/
private $length;
/**
* @ORM\Column(name="filesize", type="integer", nullable=true)
*/
private $filesize;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Tag", inversedBy="images", cascade={"persist"})
* @ORM\JoinTable(
* name="rel_tags_images",
* joinColumns={ @ORM\JoinColumn(name="image_id", referencedColumnName="id", onDelete="CASCADE") },
* inverseJoinColumns={ @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="CASCADE") }
* )
*/
private $tags;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\SingleProduct", inversedBy="images")
* @ORM\JoinColumn(name="product_id", nullable=true, onDelete="CASCADE")
*/
private $singleProduct;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Demo1", inversedBy="files")
* ORM\@ORM\JoinColumn(nullable=false)
*/
public $myfiles;
/**
* Image constructor.
*/
public function __construct()
{
$this->tags = new ArrayCollection();
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return string|null
*/
public function getMimeType(): ?string
{
return $this->mimeType;
}
/**
* @param string $mimeType
*/
public function setMimeType(string $mimeType): void
{
$this->mimeType = $mimeType;
}
/**
* @return string|null
*/
public function getUrl(): ?string
{
return $this->url;
}
/**
* @param string $url
*/
public function setUrl(string $url): void
{
$this->url = $url;
}
/**
* @return int|null
*/
public function getWidth(): ?int
{
return $this->width;
}
/**
* @param int $width
*/
public function setWidth(int $width): void
{
$this->width = $width;
}
/**
* @return int|null
*/
public function getLength(): ?int
{
return $this->length;
}
/**
* @param int $length
*/
public function setLength(int $length): void
{
$this->length = $length;
}
/**
* @return int|null
*/
public function getFilesize(): ?int
{
return $this->filesize;
}
/**
* @param int $filesize
*/
public function setFilesize(int $filesize): void
{
$this->filesize = $filesize;
}
/**
* @return Collection|Tag[]
*/
public function getTags(): Collection
{
return $this->tags;
}
/**
* @param \App\Entity\Tag $tag
*/
public function addTag(Tag $tag): void
{
if (!$this->tags->contains($tag)) {
$this->tags[] = $tag;
}
}
/**
* @param \App\Entity\Tag $tag
*/
public function removeTag(Tag $tag): void
{
if ($this->tags->contains($tag)) {
$this->tags->removeElement($tag);
}
}
/**
* @return string
*/
public function toString(): string
{
return (string)$this->getUrl();
}
/**
* @return array
*/
public function toArray(): array
{
return [
'mimetype' => $this->getMimeType(),
'url' => $this->getUrl(),
'width' => $this->getWidth(),
'length' => $this->getLength(),
'filesize' => $this->getFilesize(),
'tags' => array_map(
function (TagInterface $tag) {
return $tag->toString();
},
$this->getTags()->toArray()
),
];
}
/**
* @return \App\Entity\SingleProduct|null
*/
public function getSingleProduct(): ?SingleProduct
{
return $this->singleProduct;
}
/**
* @param \App\Entity\SingleProduct|null $singleProduct
*/
public function setSingleProduct(?SingleProduct $singleProduct): void
{
$this->singleProduct = $singleProduct;
}
/**
* @return mixed
*/
public function getFiles()
{
return $this->files;
}
/**
* @param mixed $files
*/
public function setFiles($files): void
{
$this->files = $files;
}
public function getMyfiles(): ?Demo1
{
return $this->myfiles;
}
public function setMyfiles(?Demo1 $myfiles): self
{
$this->myfiles = $myfiles;
return $this;
}
}
ImageType(窗体)
<?php
namespace App\Form;
use App\Entity\Demo1;
use App\Entity\Image;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('files', FileType::class, [
'multiple'=>true,
'attr' => [
'accept' => 'image/*',
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Demo1::class,
'csrf_protection' => false
]);
}
public function getBlockPrefix()
{
return '';
}
}
上载动作
<?php
namespace App\Controller;
use ApiPlatform\Core\Validator\Exception\ValidationException;
use ApiPlatform\Core\Validator\ValidatorInterface;
use App\Entity\Demo1;
use App\Entity\Image;
use App\Form\ImageType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
class UploadImageAction
{
/**
* @var FormFactoryInterface
*/
private $formFactory;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var ValidatorInterface
*/
private $validator;
public function __construct(
FormFactoryInterface $formFactory,
EntityManagerInterface $entityManager,
ValidatorInterface $validator
)
{
$this->formFactory = $formFactory;
$this->entityManager = $entityManager;
$this->validator = $validator;
}
public function __invoke(Request $request)
{
// Create a new Image instance
$image = new Demo1();
// Validate the form
$form = $this->formFactory->create(ImageType::class, $image);
$form->handleRequest($request);
// dump($request);
if ($form->isSubmitted() && $form->isValid()){
// Persist the new Image entity
$this->entityManager->persist($image);
$this->entityManager->flush();
// $image->setFiles(null);
return $image;
}
// Uploading done for us in background by VichUploader
// Throw an validation exception, that means something went wrong during
// form validation
throw new ValidationException(
$this->validator->validate($image)
);
}
}
如果有使用平台API上传多个文件的替代解决方案,建议当前代码不上传文件也不更新图像表
请在下面找到将多个附件上传到邮件的示例。
/ App / Entity / Attachment
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use App\Controller\AttachmentMessageAction;
/**
* @ApiResource(
* attributes={"pagination_enabled"=false},
* itemOperations={
* "get"={
* "access_control"="is_granted('ROLE_USER')",
* "normalization_context"={
* "groups"={"get"}
* }
* }
* },
* collectionOperations={
* "get",
* "post"={
* "method"="POST",
* "path"="/attachments",
* "controller"=AttachmentMessageAction::class,
* "defaults"={"_api_receive"=false}
* }
* }
* )
* @ORM\Entity(repositoryClass="App\Repository\AttachmentRepository")
* @Vich\Uploadable()
*/
class Attachment
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"get"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Message", inversedBy="attachments")
* @ORM\JoinColumn(nullable=true)
* @Groups({"post", "get"})
*/
private $message;
/**
* @Assert\File(
* maxSize = "2048k",
* maxSizeMessage = "File exceeds allowed size",
* mimeTypes = {"image/png","image/jpeg", "application/pdf", "application/x-pdf"},
* mimeTypesMessage = "Please upload a valid file"
* )
* @Assert\NotNull()
* @Vich\UploadableField(mapping="message_attachment", fileNameProperty="filename")
* @Groups({"post"})
* @var File
*/
private $file;
/**
* @ORM\Column(type="string", length=180)
* @Groups({"post","get-owner"})
* @var string
*/
private $filename;
/**
* @ORM\Column(type="datetime")
* @var \DateTime
*/
private $updatedAt;
/**
* Constructor
*
* @param Message $message
*/
public function __construct(Message $message = null)
{
$this->message = $message;
}
public function getId()
{
return $this->id;
}
public function getMessage(): ?Message
{
return $this->message;
}
public function setMessage(?Message $message): self
{
$this->message = $message;
return $this;
}
/**
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $attachment
*/
public function setFile(?File $file = null): void
{
$this->file = $file;
if (null !== $file) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getFile(): ?File
{
return $this->file;
}
public function getFilename(): ?string
{
return $this->filename;
}
public function setFilename(?string $filename): void
{
$this->filename = $filename;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function __toString()
{
return $this->id . ':' . $this->filename;
}
}
和App / Controller / AttachmentMessageAction
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use ApiPlatform\Core\Validator\ValidatorInterface;
use ApiPlatform\Core\Validator\Exception\ValidationException;
use App\Entity\Attachment;
use App\Entity\Message;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\HttpFoundation\Request;
class AttachmentMessageAction extends AbstractController
{
/**
* @var ValidatorInterface
*/
private $validator;
/**
* @var EntityManagerInterface
*/
private $entityManager;
public function __construct(
ValidatorInterface $validator,
EntityManagerInterface $entityManager
)
{
$this->validator = $validator;
$this->entityManager = $entityManager;
}
public function __invoke(Request $request)
{
$files = $request->files->get('file');
$attachments = [];
foreach ($files as $file) {
$attachment = new Attachment();
$attachment->setFile($file);
$this->validator->validate($attachment);
$this->entityManager->persist($attachment);
$attachment->setFile(null);
$attachments[] = $attachment;
}
$this->entityManager->flush();
return $attachments;
}
}