问题描述
我在 PHP Symfony 项目中使用 EasyAdminBundle。在管理员中,我在编辑和详细信息视图中显示 NumberFields 纬度和经度时遇到问题,因为 EasyAdmin 不显示存储在数据库中的值,这些值仅四舍五入为 3 位小数,而不是存储在数据库中的所有小数.
您可以在下面看到我的 ActionCrudController:
<?PHP
namespace App\Controller\Admin;
use App\Entity\Action;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Symfony\Component\Routing\Annotation\Route;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TelephoneField;
use EasyCorp\Bundle\EasyAdminBundle\Field\UrlField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action as EasyCorpAction;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
class ActionCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Action::class;
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->hideOnForm(),TextField::new('name'),TextEditorField::new('description')->hideOnIndex(),TextareaField::new('address'),TextField::new('city')->hideOnIndex(),TextField::new('postal_code')->hideOnIndex(),TextField::new('email'),TelephoneField::new('phone'),UrlField::new('website')->hideOnIndex(),TextEditorField::new('opening_hours'),NumberField::new('latitude')->hideOnIndex(),NumberField::new('longitude')->hideOnIndex(),TextareaField::new('public_accueilli_detail')->hideOnIndex(),TextareaField::new('modalite_acces')->hideOnIndex(),TextareaField::new('tarif')->hideOnIndex(),TextField::new('slug')->hideOnIndex(),DateTimeField::new('created_at')->onlyOnIndex(),DateTimeField::new('updated_at')->onlyOnIndex(),AssociationField::new('operateur')->setrequired(true),AssociationField::new('sousthematiques'),AssociationField::new('public_accueilli')->hideOnIndex(),];
}
public function configureActions(Actions $actions): Actions
{
return $actions
->add(Crud::PAGE_INDEX,EasyCorpAction::DETAIL);
}
}
你可以在这里看到我的动作实体,其中纬度和经度是浮动的:
<?PHP
namespace App\Entity;
use App\Repository\ActionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=ActionRepository::class)
* @ORM\HasLifecycleCallbacks()
* @ORM\Table("action")
*/
class Action
{
use Timestamps;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string",length=255)
*/
private $name;
/**
* @ORM\Column(type="text",nullable=true)
*/
private $description;
/**
* @ORM\Column(type="string",length=255,nullable=true)
*/
private $address;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $city;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $postal_code;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $email;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $phone;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $website;
/**
* @ORM\Column(type="text",nullable=true)
*/
private $opening_hours;
/**
* @ORM\Column(type="float")
*/
private $latitude;
/**
* @ORM\Column(type="float")
*/
private $longitude;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $public_accueilli_detail;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $modalite_acces;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $tarif;
/**
* @ORM\Column(type="string",nullable=true)
*/
private $slug;
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\Column(type="datetime",nullable=true)
*/
private $updated_at;
/**
* @ORM\ManyToOne(targetEntity=Operateur::class,inversedBy="actions")
* @ORM\JoinColumn(nullable=false)
*/
private $operateur;
/**
* @ORM\ManyToMany(targetEntity=SousThematique::class,inversedBy="actions")
*/
private $sousthematiques;
/**
* @ORM\OnetoMany(targetEntity=HoraireAction::class,mappedBy="action")
*/
private $horaire_actions;
/**
* @ORM\ManyToMany(targetEntity=PublicAccueilli::class,inversedBy="actions")
*/
private $public_accueilli;
public function __construct()
{
$this->sousthematiques = new ArrayCollection();
$this->horaire_actions = new ArrayCollection();
$this->public_accueilli = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(?string $address): self
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): self
{
$this->city = $city;
return $this;
}
public function getPostalCode(): ?string
{
return $this->postal_code;
}
public function setPostalCode(?string $postal_code): self
{
$this->postal_code = $postal_code;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(?string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getWebsite(): ?string
{
return $this->website;
}
public function setWebsite(?string $website): self
{
$this->website = $website;
return $this;
}
public function getopeningHours(): ?string
{
return $this->opening_hours;
}
public function setopeningHours(?string $opening_hours): self
{
$this->opening_hours = $opening_hours;
return $this;
}
public function getLatitude(): ?float
{
return $this->latitude;
}
public function setLatitude(float $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?float
{
return $this->longitude;
}
public function setLongitude(float $longitude): self
{
$this->longitude = $longitude;
return $this;
}
public function getPublicAccueilliDetail(): ?string
{
return $this->public_accueilli_detail;
}
public function setPublicAccueilliDetail(?string $public_accueilli_detail): self
{
$this->public_accueilli_detail = $public_accueilli_detail;
return $this;
}
public function getModaliteAcces(): ?string
{
return $this->modalite_acces;
}
public function setModaliteAcces(?string $modalite_acces): self
{
$this->modalite_acces = $modalite_acces;
return $this;
}
public function getTarif(): ?string
{
return $this->tarif;
}
public function setTarif(?string $tarif): self
{
$this->tarif = $tarif;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(?string $slug): self
{
$this->slug = $slug;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updated_at;
}
public function setUpdatedAt(?\DateTimeInterface $updated_at): self
{
$this->updated_at = $updated_at;
return $this;
}
public function getoperateur(): ?Operateur
{
return $this->operateur;
}
public function setoperateur(?Operateur $operateur): self
{
$this->operateur = $operateur;
return $this;
}
/**
* @return Collection|SousThematique[]
*/
public function getSousthematiques(): Collection
{
return $this->sousthematiques;
}
public function addSousthematique(SousThematique $sousthematique): self
{
if (!$this->sousthematiques->contains($sousthematique)) {
$this->sousthematiques[] = $sousthematique;
}
return $this;
}
public function removeSousthematique(SousThematique $sousthematique): self
{
$this->sousthematiques->removeElement($sousthematique);
return $this;
}
/**
* @return Collection|HoraireAction[]
*/
public function getHoraireActions(): Collection
{
return $this->horaire_actions;
}
public function addHoraireAction(HoraireAction $horaireAction): self
{
if (!$this->horaire_actions->contains($horaireAction)) {
$this->horaire_actions[] = $horaireAction;
$horaireAction->setAction($this);
}
return $this;
}
public function removeHoraireAction(HoraireAction $horaireAction): self
{
if ($this->horaire_actions->removeElement($horaireAction)) {
// set the owning side to null (unless already changed)
if ($horaireAction->getAction() === $this) {
$horaireAction->setAction(null);
}
}
return $this;
}
/**
* @return Collection|PublicAccueilli[]
*/
public function getPublicAccueilli(): Collection
{
return $this->public_accueilli;
}
public function addPublicAccueilli(PublicAccueilli $public_accueilli): self
{
if (!$this->public_accueilli->contains($public_accueilli)) {
$this->public_accueilli[] = $public_accueilli;
}
return $this;
}
public function removePublicAccueilli(PublicAccueilli $public_accueilli): self
{
$this->public_accueilli->removeElement($public_accueilli);
return $this;
}
public function __toString()
{
return $this->name;
}
}
我一直在尝试多种解决方案,例如:
- 修改ActionCrudController中的纬度和经度表单字段 -->
例如。 NumberField::new('longitude')->hideOnIndex()->setNumDecimals(12),
但这并不是我想要的,因为在 Detail 和 Edit 视图中没有出现存储在数据库中的确切浮点数。如果浮点数少于 12 位小数,则加 0。
- 我尝试的另一种可能性是修改操作实体:
@ORM\Column(type="float",scale=15) 私人 $latitude;
但它也不起作用。
您知道如何在 EasyAdmin 的“编辑”和“详细信息”视图中显示具有准确小数位数的纬度和经度浮点数吗?
您知道我可以在哪里配置 EasyAdmin 中 NumberField 中显示的小数位数吗?
预先感谢您的帮助!
解决方法
尝试在 Doctrine 注释中添加精度(和十进制类型)?
/**
* @ORM\Column(type="decimal",precision=9,scale=7)
*/
protected $latitude;
/**
* @ORM\Column(type="decimal",precision=10,scale=7)
*/
protected $longitude;
您可以通过调整它们来选择所需的精确度。
回复您最近的回答(关于您的数据库错误): 您收到此错误是因为您的数据库中有数据以更准确的级别存储(例如 -120.923828919)
精度=总位数(不考虑小数) 小数位数 = 小数点后多少位
MySQL 要求 Scale
你只需要调整你的精度 8 只允许 8 个数字,例如最大可能是 999.99999。纬度坐标从 -90 到 90,经度坐标从 -180 到 180,这取决于您真正需要的小数点后多远。我已经修改了我的价值观,变得更加慷慨。
抱歉,我还不能发表评论,但您可以尝试添加自定义表单类型选项吗?我不认为这归结于 EasyAdmin 本身,而是更多是从 Symfony 继承的 NumberType 字段。文档似乎指向使用“缩放”表单类型选项。
所以也许
NumberField::new('latitude')->hideOnIndex()->setFormTypeOption('scale',8)
如果您需要添加更多选项,只需使用复数形式 ->setFormTypeOptions(['scale' => 8])
。
指向此功能的直接文档链接: NumberType#scale