无法确定 class "App\Form\OrderType" 中 属性 "offerOrders" 的访问类型:属性 都不是

Could not determine access type for property "offerOrders" in class "App\Form\OrderType": Neither the property

错误是:

Could not determine access type for property "offerOrders" in class "App\Form\OrderType": Neither the property "offerOrders" nor one of the methods "addOfferOrder()"/"removeOfferOrder()", "setOfferOrders()", "offerOrders()", "__set()" or "__call()" exist and have public access in class "App\Form\OrderType"..

PhotoSession Class

    <?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;

订单Class

<?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;
    }
}

offerOrderClass

<?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;
    }
}

出价class

<?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;
    }
}

SessionPhotoType

    <?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,
        ]);
    }
}

报价订单类型

class OfferOrderType 扩展了 AbstractType { public 函数 buildForm(FormBuilderInterface $builder,数组 $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 class?

中寻找访问器

我在 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

尝试改变

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

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

或者只删除 data_class 选项