tattali / CalendarBundle

Provides event calendar for your Symfony project. Compatible with API like Google Calendar.

Home Page:https://packagist.org/packages/tattali/calendar-bundle

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting can not autowire service when using custom entity

andreyoit opened this issue · comments

I'm getting the error
Cannot autowire service "AppBundle\Entity\BusinessBooking": argument "$title" of method "CalendarBundle\Entity\Event::__construct()" is type-hinted "string", you should configure its value explicitly.

Here is my Calendar Subscriber:

<?php

namespace AppBundle\EventSubscriber;

use AppBundle\Entity\BusinessBooking;
use CalendarBundle\CalendarEvents;
//use CalendarBundle\Entity\Event;
use CalendarBundle\Event\CalendarEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class CalendarSubscriber implements EventSubscriberInterface
{
    private $bookingRepository;
    private $router;

    public function __construct(
        BusinessBooking $bookingRepository,
        UrlGeneratorInterface $router
    ) {
        $this->bookingRepository = $bookingRepository;
        $this->router = $router;
    }

    public static function getSubscribedEvents()
    {
        return [
            CalendarEvents::SET_DATA => 'onCalendarSetData',
        ];
    }

    public function onCalendarSetData(CalendarEvent $calendar)
    {
        $start = $calendar->getStart();
        $end = $calendar->getEnd();
        $filters = $calendar->getFilters();

        // Modify the query to fit to your entity and needs
        // Change booking.beginAt by your start date property
        $bookings = $this->bookingRepository
            ->createQueryBuilder('b')
            ->where('b.datetime BETWEEN :start and :end')
            ->setParameter('start', $start->format('Y-m-d H:i:s'))
            ->setParameter('end', $end->format('Y-m-d H:i:s'))
            ->getQuery()
            ->getResult()
        ;

        foreach ($bookings as $booking) {
            // this create the events with your data (here booking data) to fill calendar
            $bookingEvent = new BusinessBooking(
                $title = $booking->getUid()->getUsername(),
                $start = $booking->getDatetime() ,
                $end = $booking->getDatetime()  // If the end date is null or not defined, a all day event is created.
            );
            

            $bookingEvent->setOptions([
                'backgroundColor' => 'red',
                'borderColor' => 'red',
            ]);
            $bookingEvent->addOption(
                'url',
                $this->router->generate('booking_show', [
                    'id' => $booking->getId(),
                ])
            );

            // finally, add the event to the CalendarEvent to fill the calendar
            $calendar->addEvent($bookingEvent);
        }
    }
}

My Entity BusinessBooking extends CalendarBundle\Entity\Event.

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use \CalendarBundle\Entity\Event;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\BusinessBookingRepository")
 */
class BusinessBooking extends Event
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="businessBookings")
     * @ORM\JoinColumn(nullable=false)
     */
    private $uid;

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

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category")
     */
    private $itemCategory;

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

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

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

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

    public function getUid(): ?User
    {
        return $this->uid;
    }

    public function setUid(?User $uid): self
    {
        $this->uid = $uid;

        return $this;
    }

    public function getDatetime(): ?\DateTimeInterface
    {
        return $this->datetime;
    }

    public function setDatetime(\DateTimeInterface $datetime): self
    {
        $this->datetime = $datetime;

        return $this;
    }

    public function getItemCategory(): ?Category
    {
        return $this->itemCategory;
    }

    public function setItemCategory(?Category $itemCategory): self
    {
        $this->itemCategory = $itemCategory;

        return $this;
    }

    public function getIsAccepted(): ?bool
    {
        return $this->isAccepted;
    }

    public function setIsAccepted(?bool $isAccepted): self
    {
        $this->isAccepted = $isAccepted;

        return $this;
    }

    public function getIsDone(): ?bool
    {
        return $this->isDone;
    }

    public function setIsDone(?bool $isDone): self
    {
        $this->isDone = $isDone;

        return $this;
    }

    public function getMessage(): ?string
    {
        return $this->message;
    }

    public function setMessage(?string $message): self
    {
        $this->message = $message;

        return $this;
    }
}

If I'm not extending Event in BusinessBooking Entity, I Get:
Attempted to call an undefined method named "createQueryBuilder" of class "AppBundle\Entity\BusinessBooking".

Hi, at the instantiation of a doctrine object, setters are called with empty or default values.
In my opinion, this would be wrong to change the CalendarBundle\Entity\Event setters to accept null value because the types would become wrong.
So you should not extend CalendarBundle\Entity\Event.
Or you should rewrite setter like this public function setTitle(?string $title) for start too and probalbly getters too.
And rewrite the constructor.

You also should add doctrine annotation to props you want to save in database :

    /**
     * @ORM\Column(type="string")
     */
    private $title;

Hope this help

I've tried copy-paste the whole Events Entity getter setters, with relatives db columns declaration, Don't care about rewrite the preexisting logic. But the problem still there,

Cannot autowire service "AppBundle\Entity\BusinessBooking": argument "$title" of method "__construct()" is type-hinted "string", you should configure its value explicitly.

Hi, I edited my comment, you should also rewrite the constructor.
But I don't think all of these efforts are worth it.
At this point it's better not to extend it!

Thanks you, now it's working as expected

Do you still extends the class ?