检查日期是否已存在于另一个时间段内

时间:2014-12-24 16:24:45

标签: php symfony doctrine sonata-admin sonata

我有一个管理员可以创建新时间段的页面。现在,当管理员想要添加新的期间时,我想检查是否还有其他期限。

这是我目前的代码,但我猜<=>=在教条中不应该像他们一样工作?

$formMapper->getFormBuilder()->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
  try {
    $from = str_replace('/', '-', $event->getData()['from']);
    $to = str_replace('/', '-', $event->getData()['to']);

    $dateFrom = new \DateTime($from, new \DateTimeZone('Europe/Amsterdam'));
    $dateFrom = $dateFrom->format('Y-d-m');

    $dateTo = new \DateTime($to, new \DateTimeZone('Europe/Amsterdam'));
    $dateTo = $dateTo->format('Y-d-m');

    $query = $this->getModelManager()->createQuery('PeriodeBundle:Periode', 'p');

    $query->select()
      ->where(':from = p.from')
      ->andWhere(':to = p.to')
      ->setParameter('from', $dateFrom)
      ->setParameter('to', $dateTo);

    $data = $query->execute();

    if (count($data) > 0) {
      $event->getForm()->addError(new FormError('This period overwrites another existing period ('
         . $data[0]->getFrom()->format('d/m/Y') . ' to '
         . $data[0]->getTo()->format('d/m/Y') . ')'));
    }
  } catch (\Exception $e) {
      $event->getForm()->addError(new FormError('Date not valid'));
  }


 });

在我的数据库中,我有几个简化的句点:period_id, from, to

有人能指出我正确的方向吗? 当我创建一个已经存在的句点时,我的数据为NULL,当我在远期添加句点时,它会给出所有行的结果。 我了解了ltegte,但我不太清楚如何将其整合到此代码中。

此代码位于我的PeriodBundle管理员中。

2 个答案:

答案 0 :(得分:2)

我不知道Sonata如何处理表单,但我认为你应该使用验证约束而不是监听器。这是一个常见的表单示例:

private $em;

public function __construct(EntityManagerInterface $em)
{
    $this->em = $em;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver
        ->setDefaults(array(

            ...

            'constraints' => array(
                new Callback(
                    array('callback' => array($this, 'validateForm'))
                )
            )
        ));
}

public function validateForm(MyEntity $myEntity, ExecutionContextInterface $context)
{
    $valid = true;

    $from = str_replace('/', '-', $myEntity->etFrom());
    $to = str_replace('/', '-', $myEntity->getTo());

    $dateFrom = new \DateTime($from, new \DateTimeZone('Europe/Amsterdam'));
    $dateFrom = $dateFrom->format('Y-d-m');

    $dateTo = new \DateTime($to, new \DateTimeZone('Europe/Amsterdam'));
    $dateTo = $dateTo->format('Y-d-m');

    $queryBuilder = $em->createQueryBuilder();

    $query = $queryBuilder
        ->select(array('p'))
        ->from('PeriodeBundle:Periode', 'p')
        ->where($queryBuilder->expr()->gte('p.from', ':from'))
        ->andWhere($queryBuilder->expr()->lte('p.to', ':to'))
        ->setParameters(array(
            'from' => $dateFrom,
            'to' => $dateTo
        ))
        ->getQuery();

    $data = $query->getArrayResult();

    if (count($data) > 0) {
      $valid = false;
    }

    // ....

    if (!$valid) {
        $context
            ->buildViolation('Invalid....')
            ->atPath('MYFIELD')
            ->addViolation()
        ;
    }

}

答案 1 :(得分:0)

尝试使用findBy方法:

$formMapper->getFormBuilder()->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
try {
    $from = str_replace('/', '-', $event->getData()['from']);
    $to = str_replace('/', '-', $event->getData()['to']);

    $dateFrom = new \DateTime($from, new \DateTimeZone('Europe/Amsterdam'));
    $dateFrom = $dateFrom->format('Y-d-m');

    $dateTo = new \DateTime($to, new \DateTimeZone('Europe/Amsterdam'));
    $dateTo = $dateTo->format('Y-d-m');
    $periods_list=$this->getModelManager()->getRepository(YourClassPath)->findBy(array('from'=>$dateFrom,'to' =>$dateTo));
if (sizeof($periods_list) > 0) {
  $event->getForm()->addError(new FormError('This period overwrites another existing period ('
     . $data[0]->getFrom()->format('d/m/Y') . ' to '
     . $data[0]->getTo()->format('d/m/Y') . ')'));
}
} catch (\Exception $e) {
  $event->getForm()->addError(new FormError('Date not valid'));
}


});