AbstractDateFilter.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. $startDateParameterName = $this->getNewParameterName();
  44. $endDateParameterName = $this->getNewParameterName();
  45. if ($data['type'] == DateRangeType::TYPE_NOT_BETWEEN) {
  46. $this->applyWhere($queryBuilder, sprintf('%s.%s < :%s OR %s.%s > :%s', $alias, $field, $startDateParameterName, $alias, $field, $endDateParameterName));
  47. } else {
  48. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '>=', $startDateParameterName));
  49. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, '<=', $endDateParameterName));
  50. }
  51. $queryBuilder->setParameter($startDateParameterName, $data['value']['start']);
  52. $queryBuilder->setParameter($endDateParameterName, $data['value']['end']);
  53. } else {
  54. if (!$data['value']) {
  55. return;
  56. }
  57. //default type for simple filter
  58. $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateType::TYPE_EQUAL : $data['type'];
  59. //just find an operator and apply query
  60. $operator = $this->getOperator($data['type']);
  61. //null / not null only check for col
  62. if (in_array($operator, array('NULL', 'NOT NULL'))) {
  63. $this->applyWhere($queryBuilder, sprintf('%s.%s IS %s ', $alias, $field, $operator));
  64. } else {
  65. $parameterName = $this->getNewParameterName();
  66. $this->applyWhere($queryBuilder, sprintf('%s.%s %s :%s', $alias, $field, $operator, $parameterName));
  67. $queryBuilder->setParameter($parameterName, $data['value']);
  68. }
  69. }
  70. }
  71. /**
  72. * Resolves DataType:: constants to SQL operators
  73. * @param integer $type
  74. * @return string
  75. */
  76. protected function getOperator($type)
  77. {
  78. $type = intval($type);
  79. $choices = array(
  80. DateType::TYPE_EQUAL => '=',
  81. DateType::TYPE_GREATER_EQUAL => '>=',
  82. DateType::TYPE_GREATER_THAN => '>',
  83. DateType::TYPE_LESS_EQUAL => '<=',
  84. DateType::TYPE_LESS_THAN => '<',
  85. DateType::TYPE_NULL => 'NULL',
  86. DateType::TYPE_NOT_NULL => 'NOT NULL',
  87. );
  88. return isset($choices[$type]) ? $choices[$type] : '=';
  89. }
  90. /**
  91. * Gets default options
  92. * @return array
  93. */
  94. public function getDefaultOptions()
  95. {
  96. return array();
  97. }
  98. /**
  99. * Gets render settings
  100. * @return array
  101. */
  102. public function getRenderSettings()
  103. {
  104. $name = 'sonata_type_filter_date';
  105. if ($this->time) {
  106. $name .= 'time';
  107. }
  108. if ($this->range) {
  109. $name .= '_range';
  110. }
  111. return array($name, array(
  112. 'field_type' => $this->getFieldType(),
  113. 'field_options' => $this->getFieldOptions(),
  114. 'label' => $this->getLabel()
  115. ));
  116. }
  117. }