我目前正在尝试创建表单,以便用户可以为公司添加(多个)营业时间。 创建表单工作正常,但编辑表单似乎不断抛出此错误。
无法转换属性路径的值" [open_time]":预期a \ DateTimeInterface。
当我改变" open_time"在我的 BusinessHoursType 表单类型中,从 TimeType 到 TextType 。它似乎工作正常。但是用户必须在与小时/分钟下拉菜单相对的文本字段中输入数据。 我还使用输入的时间和日期检查特定公司是否开放。
如何让它与TimeType一起使用? 我觉得我在这里可以忽视一些小事。
商家实体
class Business
{
use TimestampTrait;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*
* @Assert\NotBlank()
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="text")
*
* @Assert\NotBlank()
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="website", type="string", length=255, nullable=true)
* @Assert\Url()
*/
private $website;
/**
* @var string
*
* @ORM\Column(name="phone", type="string", length=255, nullable=true)
*
* @Assert\NotBlank()
* @Assert\Regex(
* pattern="/^((\+|00)32\s?|0)(\d\s?\d{3}|\d{2}\s?\d{2})(\s?\d{2}){2}$/",
* message="Gelieve een geldig telefoonnummer in te vullen"
* )
*/
//TODO: regex belgian mobile number (/^((\+|00)32\s?|0)4(60|[789]\d)(\s?\d{2}){3}$/)
private $phone;
/**
* @var bool
*
* @ORM\Column(name="open_24h", type="boolean", options={"default"=false})
*/
private $open24h;
/**
* @var array
*
* @ORM\Column(name="operation_hours", type="json_array")
*/
private $businessHours;
/**
* @var int
*
* @ORM\Column(name="page_views", type="integer", options={"default"=0})
*/
private $pageViews;
/**
* @var string
*
* @ORM\Column(name="google_places_place_id", type="string", length=255, nullable=true, unique=true)
*/
private $googlePlacesPlaceId;
/**
* @var string
*
* @ORM\Column(name="foursquare_venue_id", type="string", length=255, nullable=true, unique=true)
*/
private $foursquareVenueId;
// Member Variables for Relationships.
// -----------------------------------
/**
* Many Businesses have One Merchant.
* @ORM\ManyToOne(targetEntity="Merchant", inversedBy="businesses")
* @ORM\JoinColumn(name="merchant_id", referencedColumnName="id")
*/
private $merchant;
/**
* One Business has One Address.
* @ORM\OneToOne(targetEntity="Address", mappedBy="business")
* @ORM\JoinColumn(name="address_id", referencedColumnName="id")
*
* @Assert\Valid()
*/
private $address;
/**
* One Business has many Review.
* @ORM\OneToMany(targetEntity="Review", mappedBy="business")
*/
private $reviews;
/**
* Many Businesses have One Business Type.
* @ORM\ManyToOne(targetEntity="BusinessType", inversedBy="businesses")
* @ORM\JoinColumn(name="businessType_id", referencedColumnName="id")
*/
private $businessType;
/**
* One Business has Many Images.
* @ORM\OneToMany(targetEntity="Image", mappedBy="business")
*/
private $images;
/**
* One Business has Many Promotions.
* @ORM\OneToMany(targetEntity="Promotion", mappedBy="business")
*/
private $promotions;
/**
* One Business has Many Prdocuts.
* @ORM\OneToMany(targetEntity="Product", mappedBy="business")
*/
private $products;
/**
* Business constructor.
*/
public function __construct()
{
$this->setCreatedAt(new DateTime());
$this->setUpdatedAt(new DateTime());
$this->setPageViews(0);
$this->setReviews(new ArrayCollection());
$this->setImages(new ArrayCollection());
$this->setPromotions(new ArrayCollection());
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Business
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* @param string $description
*
* @return Business
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set website
*
* @param string $website
*
* @return Business
*/
public function setWebsite($website)
{
$this->website = $website;
return $this;
}
/**
* Get website
*
* @return string
*/
public function getWebsite()
{
return $this->website;
}
/**
* Set phone
*
* @param string $phone
*
* @return Business
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set open24h
*
* @param boolean $open24h
*
* @return Business
*/
public function setOpen24h($open24h)
{
$this->open24h = $open24h;
return $this;
}
/**
* Get open24h
*
* @return bool
*/
public function getOpen24h()
{
return $this->open24h;
}
/**
* @return array
*/
public function getBusinessHours(): ?array
{
return $this->businessHours;
}
/**
* @param array $businessHours
*/
public function setBusinessHours(array $businessHours)
{
$this->businessHours = $businessHours;
}
public function addBusinessHours(array $businessHours)
{
$this->businessHours->add($businessHours);
}
public function removeBusinessHours(array $businessHours)
{
$this->businessHours->removeElement($businessHours);
}
/**
* Set pageViews
*
* @param integer $pageViews
*
* @return Business
*/
public function setPageViews($pageViews)
{
$this->pageViews = $pageViews;
return $this;
}
/**
* Get pageViews
*
* @return int
*/
public function getPageViews()
{
return $this->pageViews;
}
/**
* Set googlePlacesPlaceId
*
* @param string $googlePlacesPlaceId
*
* @return Business
*/
public function setGooglePlacesPlaceId($googlePlacesPlaceId)
{
$this->googlePlacesPlaceId = $googlePlacesPlaceId;
return $this;
}
/**
* Get googlePlacesPlaceId
*
* @return string
*/
public function getGooglePlacesPlaceId()
{
return $this->googlePlacesPlaceId;
}
/**
* Set foursquareVenueId
*
* @param string $foursquareVenueId
*
* @return Business
*/
public function setFoursquareVenueId($foursquareVenueId)
{
$this->foursquareVenueId = $foursquareVenueId;
return $this;
}
/**
* Get foursquareVenueId
*
* @return string
*/
public function getFoursquareVenueId()
{
return $this->foursquareVenueId;
}
// Member Methods for Relationships.
// ---------------------------------
/**
* Set Merchant
*
* @param Merchant $merchant
*
* @return Business
*/
public function setMerchant(Merchant $merchant)
{
$this->merchant = $merchant;
return $this;
}
/**
* Get Merchant
*
* @return Merchant
*/
public function getMerchant()
{
return $this->merchant;
}
/**
* Set Address
*
* @param Address $address
*
* @return Business
*/
public function setAddress(Address $address)
{
$this->address = $address;
return $this;
}
/**
* Get Address
*
* @return Address
*/
public function getAddress()
{
return $this->address;
}
/**
* Get Reviews.
*
* @return ArrayCollection
*/
public function getReviews()
{
return $this->reviews;
}
/**
* Set Reviews.
*
* @param ArrayCollection $reviews
*
* @return Business
*/
public function setReviews(ArrayCollection $reviews)
{
$this->reviews = $reviews;
return $this;
}
/**
* Add review.
*
* @param Review $review
*
* @return Business
*/
public function addReview(Review $review)
{
$this->reviews[] = $review;
return $this;
}
/**
* Get Business Type.
*
* @return BusinessType
*/
public function getBusinessType()
{
return $this->businessType;
}
/**
* Set Business Type.
*
* @param BusinessType $businessType
*
* @return Business
*/
public function setBusinessType(BusinessType $businessType)
{
$this->businessType = $businessType;
return $this;
}
/**
* Get Images.
*
* @return ArrayCollection
*/
public function getImages()
{
return $this->images;
}
/**
* Set Images.
*
* @param ArrayCollection $images
*
* @return Business
*/
public function setImages(ArrayCollection $images)
{
$this->images = $images;
return $this;
}
/**
* Add image
*
* @param Image $image
*
* @return $this
*/
public function addImage(Image $image)
{
$this->images[] = $image;
return $this;
}
/**
* Get Promotions.
*
* @return ArrayCollection
*/
public function getPromotions()
{
return $this->promotions;
}
/**
* Set Promotions.
*
* @param ArrayCollection $promotions
*
* @return Business
*/
public function setPromotions(ArrayCollection $promotions)
{
$this->promotions = $promotions;
return $this;
}
/**
* Add Promotion
*
* @param Promotion $promotion
*
* @return $this
*/
public function addPromotion(Promotion $promotion)
{
$this->promotions[] = $promotion;
return $this;
}
/**
* Get Products
* @return Product
*/
public function getProducts()
{
return $this->products;
}
/**
* Set Product
*
* @param Product $products
*/
public function setProducts(Product $products)
{
$this->products = $products;
}
public function addProduct(Product $product)
{
$this->products[] = $product;
return $this;
}
/**
* Check if the business is open
*/
public function isOpen()
{
$curDate = new DateTime();
$curDay = (int)$curDate->format('N');
$curTime = $curDate->format('H:i:s');
$businessHours = $this->getBusinessHours();
$isOpen = $this->getOpen24h();
if (!$this->getOpen24h()) {
foreach ($businessHours as $hoursSet) {
$openTime = date('H:i:s', strtotime($hoursSet['open_time']['date']));
$closeTime = date('H:i:s', strtotime($hoursSet['close_time']['date']));
if (in_array($curDay, $hoursSet["day"]) && $curTime >= $openTime && $curTime <= $closeTime) {
$isOpen = true;
};
}
}
return $isOpen;
}
public function __toString()
{
return $this->getName();
}
}
BusinessController
public function editAction(Request $request, Business $business)
{
$deleteForm = $this->createDeleteForm($business);
//createForm seems to be giving me the error.
$editForm = $this->createForm('AppBundle\Form\BusinessType', $business);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
//TODO: translations
$this->addFlash(
'success',
'Saved Changes'
);
return $this->redirectToRoute('business_edit', ['id' => $business->getId()]);
}
return $this->render('business/edit.html.twig',
[
'business' => $business,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
]
);
}
BusinessType
$builder->add('businessHours',
CollectionType::class,
[
'entry_type' => BusinessHoursType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
]
);
BusinessHoursType
class BusinessHoursType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('day',
ChoiceType::class,
[
'label' => 'label.day',
'translation_domain' => 'base',
'choices' => array_flip(DateConstants::DAYS),
'expanded' => true,
'multiple' => true,
]
);
$builder->add('open_time',
TimeType::class,
[
'label' => 'label.open_time',
'translation_domain' => 'business',
'input' => 'datetime',
'minutes' => [
0,
15,
30,
45,
],
'attr' => [
'class' => 'time-selector',
],
]
);
$builder->add('close_time',
TimeType::class,
[
'label' => 'label.close_time',
'translation_domain' => 'business',
'input' => 'datetime',
'minutes' => [
0,
15,
30,
45,
],
'attr' => [
'class' => 'time-selector',
],
]
);
}
}
所有内容都在我的数据库中保存为1个名为business_hours的属性,如下所示:
[{"day":[1,3],"open_time":{"date":"1970-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe\/Brussels"},"close_time":{"date":"1970-01-01 21:00:00.000000","timezone_type":3,"timezone":"Europe\/Brussels"}}]
我的 newAction 如下(它可以保存数据库中的所有内容,包括营业时间
public function newAction(Request $request)
{
$business = new Business();
$form = $this->createForm(BusinessType::class, $business);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$address = $form->get('address')->getData();
$business->setAddress($address);
$em = $this->getDoctrine()->getManager();
$em->persist($address);
$em->persist($business);
$em->flush();
$this->addFlash(
'success',
$this->get('translator')->trans('business.message.created')
);
return $this->redirectToRoute('business_show', ['id' => $business->getId()]);
}
return $this->render('business/new.html.twig',
[
'business' => $business,
'form' => $form->createView(),
]
);
}