123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- <?php
- namespace Sonata\DoctrineORMAdminBundle\Filter;
- use Sonata\AdminBundle\Form\Type\Filter\DateType;
- use Sonata\AdminBundle\Form\Type\Filter\DateRangeType;
- use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
- use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
- abstract class AbstractDateFilter extends Filter
- {
- /**
- * Flag indicating that filter will have range
- * @var boolean
- */
- protected $range = false;
- /**
- * Flag indicating that filter will filter by datetime instead by date
- * @var boolean
- */
- protected $time = false;
- /**
- *
- * @param \Doctrine\ORM\QueryBuilder $queryBuilder
- * @param string $alias
- * @param string $field
- * @param array $data
- * @return
- */
- public function filter($queryBuilder, $alias, $field, $data)
- {
- //check data sanity
- if (!$data || !is_array($data) || !array_key_exists('value', $data)) {
- return;
- }
- if ($this->range) {
- //additional data check for ranged items
- if (!array_key_exists('start', $data['value']) || !array_key_exists('end', $data['value'])) {
- return;
- }
- if (!$data['value']['start'] || !$data['value']['end']) {
- return;
- }
- //default type for range filter
- $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateRangeType::TYPE_BETWEEN : $data['type'];
- if ($data['type'] == DateRangeType::TYPE_NOT_BETWEEN) {
- $this->applyWhere($queryBuilder, sprintf('%s.%s < :%s OR %s.%s > :%s', $alias, $field, $this->getName().'_start', $alias, $field, $this->getName().'_end'));
- } else {
- $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '>=', $this->getName().'_start'));
- $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '<=', $this->getName().'_end'));
- }
- $queryBuilder->setParameter($this->getName().'_start', $data['value']['start']);
- $queryBuilder->setParameter($this->getName().'_end', $data['value']['end']);
- } else {
- if (!$data['value']) {
- return;
- }
- //default type for simple filter
- $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateType::TYPE_EQUAL : $data['type'];
- //just find an operator and apply query
- $operator = $this->getOperator($data['type']);
- //null / not null only check for col
- if (in_array($operator, array('NULL', 'NOT NULL'))) {
- $this->applyWhere($queryBuilder, sprintf('%s.%s IS %s ', $alias, $field, $operator));
- } else {
- $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, $operator, $this->getName()));
- $queryBuilder->setParameter($this->getName(), $data['value']);
- }
- }
- }
- /**
- * Resolves DataType:: constants to SQL operators
- * @param integer $type
- * @return string
- */
- protected function getOperator($type)
- {
- $type = intval($type);
- $choices = array(
- DateType::TYPE_EQUAL => '=',
- DateType::TYPE_GREATER_EQUAL => '>=',
- DateType::TYPE_GREATER_THAN => '>',
- DateType::TYPE_LESS_EQUAL => '<=',
- DateType::TYPE_LESS_THAN => '<',
- DateType::TYPE_NULL => 'NULL',
- DateType::TYPE_NOT_NULL => 'NOT NULL',
- );
- return isset($choices[$type]) ? $choices[$type] : '=';
- }
- /**
- * Gets default options
- * @return array
- */
- public function getDefaultOptions()
- {
- return array();
- }
- /**
- * Gets render settings
- * @return array
- */
- public function getRenderSettings()
- {
- $name = 'sonata_type_filter_date';
- if ($this->time) {
- $name .= 'time';
- }
- if ($this->range) {
- $name .= '_range';
- }
- return array($name, array(
- 'field_type' => $this->getFieldType(),
- 'field_options' => $this->getFieldOptions(),
- 'label' => $this->getLabel()
- ));
- }
- }
|