AbstractDateFilter.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. namespace Sonata\DoctrineORMAdminBundle\Filter;
  3. use Sonata\AdminBundle\Form\Type\Filter\DateType;
  4. use Sonata\AdminBundle\Form\Type\Filter\DateRangeType;
  5. use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
  6. use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
  7. abstract class AbstractDateFilter extends Filter
  8. {
  9. /**
  10. * Flag indicating that filter will have range
  11. * @var boolean
  12. */
  13. protected $range = false;
  14. /**
  15. * Flag indicating that filter will filter by datetime instead by date
  16. * @var boolean
  17. */
  18. protected $time = false;
  19. /**
  20. *
  21. * @param \Doctrine\ORM\QueryBuilder $queryBuilder
  22. * @param string $alias
  23. * @param string $field
  24. * @param array $data
  25. * @return
  26. */
  27. public function filter($queryBuilder, $alias, $field, $data)
  28. {
  29. //check data sanity
  30. if (!$data || !is_array($data) || !array_key_exists('value', $data)) {
  31. return;
  32. }
  33. if ($this->range) {
  34. //additional data check for ranged items
  35. if (!array_key_exists('start', $data['value']) || !array_key_exists('end', $data['value'])) {
  36. return;
  37. }
  38. if (!$data['value']['start'] || !$data['value']['end']) {
  39. return;
  40. }
  41. //default type for range filter
  42. $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateRangeType::TYPE_BETWEEN : $data['type'];
  43. if ($data['type'] == DateRangeType::TYPE_NOT_BETWEEN) {
  44. $this->applyWhere($queryBuilder, sprintf('%s.%s < :%s OR %s.%s > :%s', $alias, $field, $this->getName().'_start', $alias, $field, $this->getName().'_end'));
  45. } else {
  46. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '>=', $this->getName().'_start'));
  47. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '<=', $this->getName().'_end'));
  48. }
  49. $queryBuilder->setParameter($this->getName().'_start', $data['value']['start']);
  50. $queryBuilder->setParameter($this->getName().'_end', $data['value']['end']);
  51. } else {
  52. if (!$data['value']) {
  53. return;
  54. }
  55. //default type for simple filter
  56. $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateType::TYPE_EQUAL : $data['type'];
  57. //just find an operator and apply query
  58. $operator = $this->getOperator($data['type']);
  59. //null / not null only check for col
  60. if (in_array($operator, array('NULL', 'NOT NULL'))) {
  61. $this->applyWhere($queryBuilder, sprintf('%s.%s IS %s ', $alias, $field, $operator));
  62. } else {
  63. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, $operator, $this->getName()));
  64. $queryBuilder->setParameter($this->getName(), $data['value']);
  65. }
  66. }
  67. }
  68. /**
  69. * Resolves DataType:: constants to SQL operators
  70. * @param integer $type
  71. * @return string
  72. */
  73. protected function getOperator($type)
  74. {
  75. $type = intval($type);
  76. $choices = array(
  77. DateType::TYPE_EQUAL => '=',
  78. DateType::TYPE_GREATER_EQUAL => '>=',
  79. DateType::TYPE_GREATER_THAN => '>',
  80. DateType::TYPE_LESS_EQUAL => '<=',
  81. DateType::TYPE_LESS_THAN => '<',
  82. DateType::TYPE_NULL => 'NULL',
  83. DateType::TYPE_NOT_NULL => 'NOT NULL',
  84. );
  85. return isset($choices[$type]) ? $choices[$type] : '=';
  86. }
  87. /**
  88. * Gets default options
  89. * @return array
  90. */
  91. public function getDefaultOptions()
  92. {
  93. return array();
  94. }
  95. /**
  96. * Gets render settings
  97. * @return array
  98. */
  99. public function getRenderSettings()
  100. {
  101. $name = 'sonata_type_filter_date';
  102. if ($this->time) {
  103. $name .= 'time';
  104. }
  105. if ($this->range) {
  106. $name .= '_range';
  107. }
  108. return array($name, array(
  109. 'field_type' => $this->getFieldType(),
  110. 'field_options' => $this->getFieldOptions(),
  111. 'label' => $this->getLabel()
  112. ));
  113. }
  114. }