Datagrid.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Bundle\BaseApplicationBundle\Tool;
  11. use Bundle\BaseApplicationBundle\Tool\DoctrinePager as Pager;
  12. use Bundle\BaseApplicationBundle\Filter\StringFilter;
  13. use Bundle\BaseApplicationBundle\Filter\BooleanFilter;
  14. use Bundle\BaseApplicationBundle\Filter\IntegerFilter;
  15. use Bundle\BaseApplicationBundle\Filter\CallbackFilter;
  16. use Bundle\BaseApplicationBundle\Filter\ChoiceFilter;
  17. class Datagrid
  18. {
  19. protected $classname;
  20. protected $entity_manager;
  21. /**
  22. * The filter descriptions
  23. * @var array
  24. */
  25. protected $filter_fields = array();
  26. /**
  27. *
  28. * The filter instances
  29. * @var array
  30. */
  31. protected $filters;
  32. protected $values;
  33. protected $pager;
  34. public function __construct($classname, $entity_manager, $values = array())
  35. {
  36. $this->classname = $classname;
  37. $this->entity_manager = $entity_manager;
  38. $this->values = $values;
  39. }
  40. public function getClassMetaData()
  41. {
  42. $em = $this->getEntityManager();
  43. return $em->getClassMetaData($this->getClassname());
  44. }
  45. public function getPager()
  46. {
  47. if(!$this->pager) {
  48. $this->pager = new Pager($this->getClassname());
  49. $this->pager->setQueryBuilder($this->getQueryBuilder($this->values));
  50. $this->pager->setPage(isset($this->values['page']) ? $this->values['page'] : 1);
  51. $this->pager->init();
  52. }
  53. return $this->pager;
  54. }
  55. public function getResults()
  56. {
  57. $pager = $this->getPager($this->getValues());
  58. return $pager->getResults();
  59. }
  60. public function getBaseQueryBuilder()
  61. {
  62. $em = $this->getEntityManager();
  63. $repository = $em->getRepository($this->getClassname());
  64. $query_buidler = $repository
  65. ->createQueryBuilder('o');
  66. return $query_buidler;
  67. }
  68. public function getQueryBuilder($values = array())
  69. {
  70. $query_buidler = $this->getBaseQueryBuilder();
  71. foreach($this->getFilters() as $name => $filter) {
  72. $value = isset($values[$name]) ? $values[$name] : null;
  73. $filter->apply($query_buidler, $value);
  74. }
  75. return $query_buidler;
  76. }
  77. public function setClassname($classname)
  78. {
  79. $this->classname = $classname;
  80. }
  81. public function getClassname()
  82. {
  83. return $this->classname;
  84. }
  85. public function setEntityManager($entity_manager)
  86. {
  87. $this->entity_manager = $entity_manager;
  88. }
  89. public function getEntityManager()
  90. {
  91. return $this->entity_manager;
  92. }
  93. public function setFilterFields($filter_fields)
  94. {
  95. $this->filter_fields = $filter_fields;
  96. }
  97. public function getFilterFields()
  98. {
  99. return $this->filter_fields;
  100. }
  101. public function buildFilterFields()
  102. {
  103. $this->filter_fields = \Bundle\BaseApplicationBundle\Admin\Admin::getBaseFields($this->getClassMetaData(), $this->filter_fields);
  104. foreach($this->filter_fields as $name => $options) {
  105. $this->filter_fields[$name]['code'] = $name;
  106. // set the label if filter_fields is set
  107. if(!isset($this->filter_fields[$name]['label']))
  108. {
  109. $this->filter_fields[$name]['label'] = $name;
  110. }
  111. // set the default type if none is set
  112. if(!isset($this->filter_fields[$name]['type'])) {
  113. $this->filter_fields[$name]['type'] = 'string';
  114. }
  115. // fix template for mapping
  116. if($this->filter_fields[$name]['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_ONE) {
  117. $this->filter_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:filter_many_to_one.twig';
  118. }
  119. if($this->filter_fields[$name]['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY) {
  120. $this->filter_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:filter_many_to_many.twig';
  121. }
  122. // define the default template
  123. if(!isset($this->filter_fields[$name]['template'])) {
  124. $this->filter_fields[$name]['template'] = sprintf('BaseApplicationBundle:CRUD:filter_%s.twig', $this->filter_fields[$name]['type']);
  125. }
  126. // define the default template for identifier field
  127. if(isset($this->filter_fields[$name]['id'])) {
  128. $this->filter_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:filter_identifier.twig';
  129. }
  130. if(!isset($this->filter_fields[$name]['filter_value'])) {
  131. $this->filter_fields[$name]['filter_value'] = null;
  132. }
  133. // options given to the Filter object
  134. if(!isset($this->filter_fields[$name]['filter_options'])) {
  135. $this->filter_fields[$name]['filter_options'] = array();
  136. }
  137. // options given to the Form Field object
  138. if(!isset($this->filter_fields[$name]['filter_field_options'])) {
  139. $this->filter_fields[$name]['filter_field_options'] = array();
  140. }
  141. if(!isset($this->filter_fields[$name]['name']))
  142. {
  143. $this->filter_fields[$name]['name'] = $name;
  144. }
  145. }
  146. $this->configureFilterFields();
  147. }
  148. public function getChoices($description)
  149. {
  150. $targets = $this->getEntityManager()
  151. ->createQueryBuilder()
  152. ->select('t')
  153. ->from($description['targetEntity'], 't')
  154. ->getQuery()
  155. ->execute();
  156. $choices = array();
  157. foreach($targets as $target) {
  158. // todo : puts this into a configuration option and use reflection
  159. foreach(array('getTitle', 'getName', '__toString') as $getter) {
  160. if(method_exists($target, $getter)) {
  161. $choices[$target->getId()] = $target->$getter();
  162. break;
  163. }
  164. }
  165. }
  166. return $choices;
  167. }
  168. public function getFilterInstance($description)
  169. {
  170. if(!isset($description['type'])) {
  171. return false;
  172. }
  173. $name = $description['name'];
  174. switch($description['type']) {
  175. case \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY:
  176. $description['filter_field_options']['choices'] = $this->getChoices($description);
  177. $filter = new ChoiceFilter($name, $description);
  178. break;
  179. case 'string':
  180. case 'text':
  181. $filter = new StringFilter($name, $description);
  182. break;
  183. case 'boolean':
  184. $filter = new BooleanFilter($name, $description);
  185. break;
  186. case 'integer':
  187. $filter = new IntegerFilter($name, $description);
  188. break;
  189. case 'callback':
  190. $filter = new CallbackFilter($name, $description);
  191. break;
  192. default:
  193. return false;
  194. }
  195. return $filter;
  196. }
  197. public function configureFilterFields()
  198. {
  199. }
  200. public function getFilters()
  201. {
  202. if(!$this->filters) {
  203. foreach($this->filter_fields as $name => $description) {
  204. $filter = $this->getFilterInstance($this->filter_fields[$name]);
  205. if($filter) {
  206. $this->filters[$name] = $filter;
  207. }
  208. }
  209. }
  210. return $this->filters;
  211. }
  212. public function setValues($values)
  213. {
  214. $this->values = $values;
  215. }
  216. public function getValues()
  217. {
  218. return $this->values;
  219. }
  220. }