【问题标题】:Could not determine access type for property "offerOrders" in class "App\Form\OrderType": Neither the property无法确定类“App\Form\OrderType”中属性“offerOrders”的访问类型:该属性都不是
【发布时间】:2020-11-07 07:46:49
【问题描述】:

错误是:

无法确定“App\Form\OrderType”类中属性“offerOrders”的访问类型:属性“offerOrders”和“addOfferOrder()”/“removeOfferOrder()”、“setOfferOrders()”方法之一"、"offerOrders()"、"__set()" 或 "__call()" 存在并在类 "App\Form\OrderType" 中具有公共访问权限..

PhotoSession 类

    <?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PhotoSessionRepository")
 */
class PhotoSession
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;


    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Order", inversedBy="photoSession", cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $purchaseOrder;

订单类

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\OrderRepository")
 * @ORM\Table(name="`order`")
 */
class Order
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\PhotoSession", mappedBy="purchaseOrder", cascade={"persist", "remove"})
     */
    private $photoSession;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\OfferOrder", mappedBy="purchaseOrder", cascade={"persist"})
     */
    private $offerOrders;

    public function __construct()
    {
        $this->offerOrders = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getPhotoSession(): ?PhotoSession
    {
        return $this->photoSession;
    }

    public function setPhotoSession(PhotoSession $photoSession): self
    {
        $this->photoSession = $photoSession;

        // set the owning side of the relation if necessary
        if ($photoSession->getPurchaseOrder() !== $this) {
            $photoSession->setPurchaseOrder($this);
        }

        return $this;
    }

    /**
     * @return Collection|OfferOrder[]
     */
    public function getOfferOrders(): Collection
    {
        return $this->offerOrders;
    }

    public function addOfferOrder(OfferOrder $offerOrder): self
    {
        if (!$this->offerOrders->contains($offerOrder)) {
            $this->offerOrders[] = $offerOrder;
            $offerOrder->setPurchaseOrder($this);
        }

        return $this;
    }

    public function removeOfferOrder(OfferOrder $offerOrder): self
    {
        if ($this->offerOrders->contains($offerOrder)) {
            $this->offerOrders->removeElement($offerOrder);
            // set the owning side to null (unless already changed)
            if ($offerOrder->getPurchaseOrder() === $this) {
                $offerOrder->setPurchaseOrder(null);
            }
        }

        return $this;
    }
}

offerOrder 类

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\OfferOrderRepository")
 */
class OfferOrder
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Offer", inversedBy="offerOrders")
     * @ORM\JoinColumn(nullable=false)
     */
    private $offer;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Order", inversedBy="offerOrders")
     * @ORM\JoinColumn(nullable=false)
     */
    private $purchaseOrder;

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

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

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getOffer(): ?Offer
    {
        return $this->offer;
    }

    public function setOffer(?Offer $offer): self
    {
        $this->offer = $offer;

        return $this;
    }

    public function getPurchaseOrder(): ?Order
    {
        return $this->purchaseOrder;
    }

    public function setPurchaseOrder(?Order $purchaseOrder): self
    {
        $this->purchaseOrder = $purchaseOrder;

        return $this;
    }

    public function getQuantity(): ?float
    {
        return $this->quantity;
    }

    public function setQuantity(?float $quantity): self
    {
        $this->quantity = $quantity;

        return $this;
    }

    public function getTotalPriceHt(): ?float
    {
        return $this->totalPriceHt;
    }

    public function setTotalPriceHt(?float $totalPriceHt): self
    {
        $this->totalPriceHt = $totalPriceHt;

        return $this;
    }
}

提供类

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\OfferRepository")
 */
class Offer
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="float")
     */
    private $price;

    /**
     * @var Tag
     * @ORM\ManyToOne(targetEntity="App\Entity\Tag")
     * @ORM\JoinColumn(nullable=false)
     */
    private $tag;

    /**
     * @var integer|null
     * @ORM\Column(type="integer")
     */
    private $version = 0;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\OfferOrder", mappedBy="offer")
     */
    private $offerOrders;

    public function __construct()
    {
        $this->offerOrders = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getPrice(): ?float
    {
        return $this->price;
    }

    public function setPrice(float $price): self
    {
        $this->price = $price;

        return $this;
    }

    /**
     * @return Tag|null
     */
    public function getTag(): ?Tag
    {
        return $this->tag;
    }

    /**
     * @param Tag $tag
     * @return Offer
     */
    public function setTag(Tag $tag): self
    {
        $this->tag = $tag;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getVersion(): ?int
    {
        return $this->version;
    }

    /**
     * @param int|null $version
     * @return Offer
     */
    public function setVersion(?int $version): self
    {
        $this->version = $version;
        return $this;
    }

    /**
     * @return Collection|OfferOrder[]
     */
    public function getOfferOrders(): Collection
    {
        return $this->offerOrders;
    }

    public function addOfferOrder(OfferOrder $offerOrder): self
    {
        if (!$this->offerOrders->contains($offerOrder)) {
            $this->offerOrders[] = $offerOrder;
            $offerOrder->setOffer($this);
        }

        return $this;
    }

    public function removeOfferOrder(OfferOrder $offerOrder): self
    {
        if ($this->offerOrders->contains($offerOrder)) {
            $this->offerOrders->removeElement($offerOrder);
            // set the owning side to null (unless already changed)
            if ($offerOrder->getOffer() === $this) {
                $offerOrder->setOffer(null);
            }
        }

        return $this;
    }
}

会话照片类型

    <?php

namespace App\Form;

use App\Entity\Family;
use App\Entity\PhotoSession;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PhotoSessionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('family', EntityType::class, [
                'class' => Family::class,
                'choice_label' => 'name',
            ])
            ->add('purchaseOrder', OrderType::class, [
                'data_class' => OrderType::class
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => PhotoSession::class,
        ]);
    }
}

订单类型

<?php

namespace App\Form;

use App\Entity\Order;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class OrderType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('offerOrders', CollectionType::class, [
                'entry_type' => OfferOrderType::class,
                'by_reference' => false,
                'allow_add' => true,
                'allow_delete' => true,
            ])
            ->add('totalPriceHt')
            ->add('tva')
            ->add('finalPrice')
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Order::class,
        ]);
    }
}

OfferOrderType

类 OfferOrderType 扩展 AbstractType { 公共函数 buildForm(FormBuilderInterface $builder, array $options) { $建造者

        ->add('offer', EntityType::class, [
            'class' => Offer::class,
            'choice_label' => function(Offer $offer) {
                return sprintf('%s %f €', $offer->getTag()->getName(), $offer->getPrice());
            },
            'placeholder' => 'Choissiez une offre'
        ])
        ->add('quantity', NumberType::class)
        ->add('totalPriceHt', NumberType::class);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'widget' => 'single_text',
        'data_class' => OfferOrder::class,
    ]);
}

}

对于长代码块我很抱歉,但对于那些将尝试解决错误的人,我认为这是必要的。 提交表单时返回错误。 我问自己的问题是,为什么 symfony 会在 App\Form\OrderType 类中寻找访问器?

我在PropertyAccessor.php PropertyPathMapper.php 和vendor/symfony/form/Form.php 中到处都放了转储,当它放在这里时:

if (FormUtil::isEmpty($viewData)) {
    $emptyData = $this->config->getEmptyData();

    if ($emptyData instanceof \Closure) {
        $emptyData = $emptyData($this, $viewData);
    }

    $viewData = $emptyData;
    dump($viewData);
 }

在 Form.php 中将 $viewData 设置为 App\Form\OrderType 但我不知道为什么

答案是:

为了让表单通过,必须像这样更改 photoSessionType 中的 purchaseOrder:

-> add ('purchaseOrder', OrderType :: class)

再次感谢@Ihor Kostrov

【问题讨论】:

  • 看起来你在某处传递了 FormType,而不是实体
  • 我在 PropertyAccessor.php PropertyPathMapper.php 和 vendor / symfony / form / Form.php 中到处都放了转储,当它到这里时:if (FormUtil :: isEmpty ($ viewData)) {$ emptyData = $ this-&gt; config-&gt; getEmptyData (); if ($ emptyData instanceof \ Closure) {$ emptyData = $ emptyData ($this, $ viewData);} $ viewData = $ emptyData; dump ($ viewData);} in Form.php 它设置 $ viewData 到 App \ Form \ OrderType 但我不知道为什么

标签: symfony symfony-forms nested-forms symfony5 multiple-forms


【解决方案1】:

尝试改变

->add('purchaseOrder', OrderType::class, [
                'data_class' => OrderType::class
            ])

->add('purchaseOrder', OrderType::class, [
                'data_class' => Order::class
            ])

或者只是删除 data_class 选项

【讨论】:

  • 真的非常感谢你,我不知道为什么我没有想到在表格中看起来更高......再次感谢!
猜你喜欢
  • 2019-09-26
  • 2017-05-03
  • 2023-03-24
  • 2021-05-07
  • 1970-01-01
  • 2021-09-19
  • 2023-03-20
  • 1970-01-01
  • 2016-02-11
相关资源
最近更新 更多