具有扩展存储库类的Symfony2实体

时间:2014-11-26 11:13:07

标签: symfony override entities

我希望我能够在不烦人或让别人头疼的情况下提出这个问题。我是Symfony的新手,并试图绕过一切。

以下是我想要做的事情:在一个名为CalendarBundle的包中,我有一个Event实体,其中Repository类看起来像这样:

class EventRepository extends EntityRepository
{
    /**
     * @param $start
     * @param $end
     * @return array $events_array
     */
    public function queryByRange($start = "", $end = "")
    {
        // set start and end to this month if empty
        $start = ($start == "")
          ? date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), 1, date('Y')))
          : $start;
        $end = ($end == "")
          ? date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), date('t'), date('Y')))
          : $end;

        $query = $this->createQueryBuilder('e')
          ->where('e.start > :start')
          ->andWhere('e.end < :end')
          ->setParameter('start', $start)
          ->setParameter('end', $end)
          ->orderBy('e.start', 'ASC');

        return $query;
    }

    /**
     * @param string $start
     * @param string $end
     * @return array
     */
    public function findByRange($start = "", $end = "")
    {
        // set start and end to this month if empty
        $start = ($start == "")
          ? date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), 1, date('Y')))
          : $start;
        $end = ($end == "")
          ? date('Y-m-d H:i:s', mktime(0, 0, 0, date('m'), date('t'), date('Y')))
          : $end;

        $events = $this->queryByRange($start, $end)->getQuery()->getResult();

        $events_array = array();
        $prev_date = '';

        foreach($events as $event) {
            $start = $event->getStart()->format('Ymj');

            if ($prev_date == $start) {
                $events_array[$prev_date][] = $this->eventToArray($event);
            } else {
                $events_array[$start][] = $this->eventToArray($event);
            }

            $prev_date = $start;
        }

        return $events_array;
    }

    /**
     * @param Event $event
     * @return array
     */
    private function eventToArray(Event $event)
    {
        return array(
          'item' => array(
            'id' => $event->getId(),
            'name' => $event->getName(),
            'description' => $event->getDescription(),
            'type' => $event->getType(),
            'status' => $event->getStatus(),
            'start' => $event->getStart()->format('Ymd H:i:s'),
            'end' => $event->getEnd()->format('Ymd H:i:s'),
          ),
        );
    }
}

我想要完成的是扩展这个基本事件实体,增加几个特定事件,为每个事件添加不同的事件元数据。我认为需要重写queryByRange函数以获取元数据,eventToArray函数也是如此。

稍后我使用不同的树枝模板显示事件,使用事件项类型来决定使用的模板。

现在让我头疼的事情。因为我不知道可能存在哪些事件,所以我想在Controller中获取各种事件时使用这个EventRepository类:

$repository = $this->getDoctrine()->getRepository('AcmeCalendarBundle:Event'); 
$events = $repository->findByRange($start, $end);

并且自动使用正确的扩展类来查询和返回事件。

我发现this question where extending Bundles是正确的做法。但我不认为这解决了我的问题。

1 个答案:

答案 0 :(得分:1)

以下是我认为你想要实现的一个例子:

/**
 * @ORM\Entity(repositoryClass="My\OwnBundle\Entity\Repository\EventRepository")
 * @ORM\Table(name="event")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"sport_event" = "SportEvent", "music_event" = "MusicEvent"})
 */
class Event
{
    /**
     * @var integer
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=50)
     */
    protected $name;

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

/** @ORM\Entity */
class SportEvent extends Event
{
    /**
     * @var string
     * @ORM\Column(name="discipline", type="string", length=100)
     */
    protected $discipline;

    public function setDiscipline($discipline)
    {
        $this->discipline = $discipline;
    }

    public function getDiscipline()
    {
        return $this->discipline;
    }
}

/** @ORM\Entity */
class MusicEvent extends Event
{
    /**
     * @var string
     * @ORM\Column(name="band", type="string", length=100)
     */
    protected $band;

    public function setBand($band)
    {
        $this->band = $band;
    }

    public function getBand()
    {
        return $this->$band;
    }
}

您的事件存储库可能只是:

class EventRepository extends EntityRepository
{

}

我没有在实体上包含开始和结束字段,但假设你有它们,那么你可以这样做:

$repository->findBy(['start' => $start, 'end' => $end])

假设$ start和$ end是正确的\ DateTime对象,结果将是与指定日期范围匹配的实体列表,但每个单独的对象都是适当的类(例如,MusicEvent,SportEvent)。

在此处阅读更多内容:http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance