我有一个小问题,我卡住了,可以帮助我吗?
enter image description hereenter image description here
vich_uploader.yaml
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
ServiceImage:
uri_prefix: /assets/img_uploads/Services
upload_destination: "%kernel.project_dir%/public/assets/img_uploads/Services"
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
VehicleImage:
uri_prefix: /assets/img_uploads/Vehicles
upload_destination: "%kernel.project_dir%/public/assets/img_uploads/Vehicles"
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
文件实体
<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use App\Repository\VparServiceRepository;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Vich\UploaderBundle\Mapping\Annotation\Uploadable;
#[ORM\Entity(repositoryClass: VparServiceRepository::class)]
#[Uploadable]
class VparService
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $updatedAt = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $text = null;
#[Vich\UploadableField(mapping: 'ServiceImage', fileNameProperty: 'imageNameVehicle')]
private ?File $imageFile = null;
#[ORM\Column(nullable: true)]
private ?string $imageNameVehicle = null;
public function getId(): ?int
{
return $this->id;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): static
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getText(): ?string
{
return $this->text;
}
public function setText(string $text): static
{
$this->text = $text;
return $this;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function setImageFile(?File $imageFile = null): void
{
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// 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 getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageNameVehicle(?string $imageNameVehicle): void
{
$this->imageNameVehicle = $imageNameVehicle;
}
public function getImageNameVehicle(): ?string
{
return $this->imageNameVehicle;
}
}
fileformType
<?php
namespace App\Form;
use App\Entity\VparService;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Vich\UploaderBundle\Form\Type\VichImageType;
class ServicesType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title', TextType::class, [
'label' => 'Nom du service',
'attr' => ['class' => 'form-control'],
])
->add('text', TextareaType::class, [
'label' => 'Description du service',
'attr' => ['class' => 'form-control'],
])
->add('imageNameVehicle', VichImageType::class, [
'label' => 'Image',
'required' => false,
'attr' => ['class' => 'form-control'],
])
->add('submit', SubmitType::class, [
'label' => 'Enregistrer',
'attr' => ['class' => 'btn btn-primary'],
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => VparService::class,
]);
}
}
控制器
<?php
namespace App\Controller;
use App\Form\ServicesType;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\VparServiceRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ServicesController extends AbstractController
{
#[IsGranted('ROLE_ADMIN')]
#[Route('/back/gestion-des-services', name: 'app_services')]
public function index(VparServiceRepository $services): Response
{
return $this->render('pages/services/gServices.html.twig', [
'title_page' => 'Gestion des services | V.Parrot',
'nav_item1' => 'Retour vers le site',
'nav_item2' => 'Gestion des ventes',
'nav_item3' => 'Gestion des services',
'nav_item4' => 'Gestion des horaires',
'nav_item5' => 'Gestion des employés',
'nav_item6' => 'Gestion des avis clients',
'nav_item7' => 'Déconnexion',
'h1_index' => 'Gestion des Services',
'h2_index' => 'Service actuellement proposés',
'add_btn' => 'Ajouter un nouveau service',
'th_name' => 'Nom du service',
'th_text' => 'Description du service',
'th_img' => 'Image du service',
'td_modify' => 'Modifier',
'td_delete' => 'Supprimer',
'services' => $services->findAll(),
]);
}
#[IsGranted('ROLE_ADMIN')]
#[Route('/back/gestion-des-services/edition/{id}', name: 'app_gestion_services_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, VparServiceRepository $services, EntityManagerInterface $em, int $id): Response
{
$service = $services->find($id);
$form = $this->createForm(ServicesType::class, $service);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$service->setUpdatedAt(new \DateTime());
$em->flush();
$this->addFlash('success', 'Le service a bien été modifié.');
return $this->redirectToRoute('app_services');
}
return $this->render('pages/services/gServicesEdit.html.twig', [
'title_page' => 'modification d\'un employé | V.Parrot',
'nav_item1' => 'Retour vers le site',
'nav_item2' => 'Gestion des ventes',
'nav_item3' => 'Gestion des services',
'nav_item4' => 'Gestion des horaires',
'nav_item5' => 'Gestion des employés',
'nav_item6' => 'Gestion des avis clients',
'nav_item7' => 'Déconnexion',
'h1_edit' => 'Gestion des Services',
'h2_edit' => 'Modifier un service',
'form' => $form->createView(),
]);
}
}
菲尔特维希
{% extends "base.html.twig" %}
{% block title %}{{ title_page }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('assets/styles/general_backoffice.css') }}">
<link rel="stylesheet" href="{{ asset('assets/styles/general_form_backoffice.css') }}">
<link rel="stylesheet" href="{{ asset('assets/styles/add_modify_form_backoffice.css') }}">
<link rel="stylesheet" href="{{ asset('assets/styles/button_backoffice.css') }}">
{% endblock %}
{% block header %}
{{ include("partials/_header.html.twig") }}
{{ include("partials/_nav_back.html.twig") }}
{% endblock %}
{% block body %}
<div class="container">
<h1>{{ h1_edit }}</h1>
<h2>{{ h2_edit }}</h2>
{{ form_start(form) }}
{{ form_row(form.title) }}
{{ form_row(form.text) }}
{{ form_row(form.imageNameVehicle) }}
<div class="addBtn">
{{ form_row(form.submit) }}
</div>
{{ form_end(form) }}
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const downloadLinks = document.querySelectorAll('a[download]');
downloadLinks.forEach(link => {
if (link.textContent.toLowerCase().trim() === 'download') {
link.textContent = 'Télécharger';
}
});
const deleteLabels = document.querySelectorAll('label[for$="_delete"]');
deleteLabels.forEach(label => {
if (label.textContent.toLowerCase().trim() === 'delete?') {
label.textContent = 'Supprimer';
}
});
});
</script>
{% endblock %}
我承认,我刚刚开始,我有点迷路了。谁能给我解释一下,帮帮我。
有没有可能调试这个?并向我解释问题来自哪里,了解我的错误,以免再次重现。谢谢您的支持。
1条答案
按热度按时间am46iovg1#
根据documentation,您应该将表单字段Map到
File
属性,而不是保存文件名的属性:在您的情况下,它应该是: