AbstractDateFilter.php 4.4 KB

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