Admin.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  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\Sonata\BaseApplicationBundle\Admin;
  11. use Symfony\Component\DependencyInjection\ContainerAware;
  12. use Symfony\Component\Form\Form;
  13. use Bundle\Sonata\BaseApplicationBundle\Tool\Datagrid;
  14. abstract class Admin extends ContainerAware
  15. {
  16. protected $class;
  17. protected $listFields = false;
  18. protected $formFields = false;
  19. protected $filterFields = array(); // by default there is no filter
  20. protected $filterDatagrid;
  21. protected $maxPerPage = 25;
  22. protected $baseRouteName = '';
  23. protected $baseRoutePattern;
  24. protected $baseControllerName;
  25. protected $formGroups = false;
  26. // note : don't like this, but havn't find a better way to do it
  27. protected $configurationPool;
  28. protected $code;
  29. protected $label;
  30. protected $urls = array();
  31. protected $subject;
  32. /**
  33. * Reference the parent FieldDescription related to this admin
  34. * only set for FieldDescription which is associated to an Sub Admin instance
  35. *
  36. * FieldDescription
  37. */
  38. protected $parentFieldDescription;
  39. protected $loaded = array(
  40. 'form_fields' => false,
  41. 'form_groups' => false,
  42. 'list_fields' => false,
  43. 'urls' => false,
  44. );
  45. /**
  46. * return the entity manager
  47. *
  48. * @return EntityManager
  49. */
  50. abstract public function getEntityManager();
  51. /**
  52. * build the fields to use in the form
  53. *
  54. * @throws RuntimeException
  55. * @return
  56. */
  57. abstract public function buildFormFields();
  58. /**
  59. * build the field to use in the list view
  60. *
  61. * @return void
  62. */
  63. abstract public function buildListFields();
  64. abstract public function getChoices(FieldDescription $description);
  65. abstract public function getForm($object, $fields);
  66. public function configure()
  67. {
  68. }
  69. /**
  70. * return the baseRoutePattern used to generate the routing information
  71. *
  72. * @throws RuntimeException
  73. * @return string the baseRoutePattern used to generate the routing information
  74. */
  75. public function getBaseRoutePattern()
  76. {
  77. if (!$this->baseRoutePattern) {
  78. if (preg_match('@(Application|Bundle)\\\([A-Za-z]*)\\\([A-Za-z]*)Bundle\\\(Entity|Document)\\\([A-Za-z]*)@', $this->getClass(), $matches)) {
  79. $this->baseRoutePattern = sprintf('/%s/%s/%s',
  80. $this->urlize($matches[2], '-'),
  81. $this->urlize($matches[3], '-'),
  82. $this->urlize($matches[5], '-')
  83. );
  84. } else {
  85. throw new \RuntimeException(sprintf('Please define a default `baseRoutePattern` value for the admin class `%s`', get_class($this)));
  86. }
  87. }
  88. return $this->baseRoutePattern;
  89. }
  90. /**
  91. * return the baseRouteName used to generate the routing information
  92. *
  93. * @throws RuntimeException
  94. * @return string the baseRouteName used to generate the routing information
  95. */
  96. public function getBaseRouteName()
  97. {
  98. if (!$this->baseRouteName) {
  99. if (preg_match('@(Application|Bundle)\\\([A-Za-z]*)\\\([A-Za-z]*)Bundle\\\(Entity|Document)\\\([A-Za-z]*)@', $this->getClass(), $matches)) {
  100. $this->baseRouteName = sprintf('admin_%s_%s_%s',
  101. $this->urlize($matches[2]),
  102. $this->urlize($matches[3]),
  103. $this->urlize($matches[5])
  104. );
  105. } else {
  106. throw new \RuntimeException(sprintf('Please define a default `baseRoutePattern` value for the admin class `%s`', get_class($this)));
  107. }
  108. }
  109. return $this->baseRouteName;
  110. }
  111. public function urlize($word, $sep = '_') {
  112. return strtolower(preg_replace('~(?<=\\w)([A-Z])~', $sep.'$1', $word));
  113. }
  114. /**
  115. * return the class name handled by the Admin instance
  116. *
  117. * @return string the class name handled by the Admin instance
  118. */
  119. public function getClass()
  120. {
  121. return $this->class;
  122. }
  123. /**
  124. * return the doctrine class metadata handled by the Admin instance
  125. *
  126. * @return ClassMetadataInfo the doctrine class metadata handled by the Admin instance
  127. */
  128. public function getClassMetaData()
  129. {
  130. return $this->getEntityManager()
  131. ->getClassMetaData($this->getClass());
  132. }
  133. /**
  134. * return the list of batchs actions
  135. *
  136. * @return array the list of batchs actions
  137. */
  138. public function getBatchActions()
  139. {
  140. return array(
  141. 'delete' => 'action_delete'
  142. );
  143. }
  144. /**
  145. * return the list of available urls
  146. *
  147. * @return array the list of available urls
  148. */
  149. public function getUrls()
  150. {
  151. $this->buildUrls();
  152. return $this->urls;
  153. }
  154. public function buildUrls()
  155. {
  156. if ($this->loaded['urls']) {
  157. return;
  158. }
  159. $this->urls = array(
  160. 'list' => array(
  161. 'name' => $this->getBaseRouteName().'_list',
  162. 'pattern' => $this->getBaseRoutePattern().'/list',
  163. 'defaults' => array(
  164. '_controller' => $this->getBaseControllerName().':list'
  165. ),
  166. 'requirements' => array(),
  167. 'options' => array(),
  168. 'params' => array(),
  169. ),
  170. 'create' => array(
  171. 'name' => $this->getBaseRouteName().'_create',
  172. 'pattern' => $this->getBaseRoutePattern().'/create',
  173. 'defaults' => array(
  174. '_controller' => $this->getBaseControllerName().':create'
  175. ),
  176. 'requirements' => array(),
  177. 'options' => array(),
  178. 'params' => array(),
  179. ),
  180. 'edit' => array(
  181. 'name' => $this->getBaseRouteName().'_edit',
  182. 'pattern' => $this->getBaseRoutePattern().'/{id}/edit',
  183. 'defaults' => array(
  184. '_controller' => $this->getBaseControllerName().':edit'
  185. ),
  186. 'requirements' => array(),
  187. 'options' => array(),
  188. 'params' => array(),
  189. ),
  190. 'update' => array(
  191. 'name' => $this->getBaseRouteName().'_update',
  192. 'pattern' => $this->getBaseRoutePattern().'/update',
  193. 'defaults' => array(
  194. '_controller' => $this->getBaseControllerName().':update'
  195. ),
  196. 'requirements' => array(),
  197. 'options' => array(),
  198. 'params' => array(),
  199. ),
  200. 'batch' => array(
  201. 'name' => $this->getBaseRouteName().'_batch',
  202. 'pattern' => $this->getBaseRoutePattern().'/batch',
  203. 'defaults' => array(
  204. '_controller' => $this->getBaseControllerName().':batch'
  205. ),
  206. 'requirements' => array(),
  207. 'options' => array(),
  208. 'params' => array(),
  209. )
  210. );
  211. $this->configureUrls();
  212. }
  213. public function configureUrls()
  214. {
  215. }
  216. /**
  217. * return the url defined by the $name
  218. *
  219. * @param $name
  220. * @return bool
  221. */
  222. public function getUrl($name)
  223. {
  224. $urls = $this->getUrls();
  225. if (!isset($urls[$name])) {
  226. return false;
  227. }
  228. return $urls[$name];
  229. }
  230. /**
  231. * generate the url with the given $name
  232. *
  233. * @throws RuntimeException
  234. * @param $name
  235. * @param array $params
  236. *
  237. * @return return a complete url
  238. */
  239. public function generateUrl($name, $params = array())
  240. {
  241. $url = $this->getUrl($name);
  242. if (!$url) {
  243. throw new \RuntimeException(sprintf('unable to find the url `%s`', $name));
  244. }
  245. if (!is_array($params)) {
  246. $params = array();
  247. }
  248. return $this->container->get('router')->generate($url['name'], array_merge($url['params'], $params));
  249. }
  250. /**
  251. * return the list template
  252. *
  253. * @return string the list template
  254. */
  255. public function getListTemplate()
  256. {
  257. return 'SonataBaseApplicationBundle:CRUD:list.twig.html';
  258. }
  259. /**
  260. * return the edit template
  261. *
  262. * @return string the edit template
  263. */
  264. public function getEditTemplate()
  265. {
  266. return 'SonataBaseApplicationBundle:CRUD:edit.twig.html';
  267. }
  268. public function getReflectionFields()
  269. {
  270. return $this->getClassMetaData()->reflFields;
  271. }
  272. public function getNewInstance()
  273. {
  274. $class = $this->getClass();
  275. return new $class;
  276. }
  277. /**
  278. * attach an admin instance to the given FieldDescription
  279. *
  280. */
  281. public function attachAdminClass(FieldDescription $fieldDescription)
  282. {
  283. $pool = $this->getConfigurationPool();
  284. $admin = $pool->getAdminByClass($fieldDescription->getTargetEntity());
  285. if (!$admin) {
  286. throw new \RuntimeException(sprintf('You must define an Admin class for the `%s` field', $fieldDescription->getFieldName()));
  287. }
  288. $fieldDescription->setAssociationAdmin($admin);
  289. }
  290. /**
  291. * return the target objet
  292. *
  293. * @param $id
  294. * @return
  295. */
  296. public function getObject($id)
  297. {
  298. return $this->getEntityManager()
  299. ->find($this->getClass(), $id);
  300. }
  301. public function buildFormGroups()
  302. {
  303. if ($this->loaded['form_groups']) {
  304. return;
  305. }
  306. $this->loaded['form_groups'] = true;
  307. if (!$this->formGroups) {
  308. $this->formGroups = array(
  309. false => array('fields' => array_keys($this->formFields))
  310. );
  311. }
  312. // normalize array
  313. foreach ($this->formGroups as $name => $group) {
  314. if (!isset($this->formGroups[$name]['collapsed'])) {
  315. $this->formGroups[$name]['collapsed'] = false;
  316. }
  317. }
  318. }
  319. public function preUpdate($object)
  320. {
  321. }
  322. public function postUpdate($object)
  323. {
  324. }
  325. public function preInsert($object)
  326. {
  327. }
  328. public function postInsert($object)
  329. {
  330. }
  331. public function configureListFields()
  332. {
  333. }
  334. public function configureFilterFields()
  335. {
  336. }
  337. public function configureFormFields()
  338. {
  339. }
  340. public function getFilterDatagrid()
  341. {
  342. if (!$this->filterDatagrid) {
  343. $this->filterDatagrid = new Datagrid(
  344. $this->getClass(),
  345. $this->getEntityManager()
  346. );
  347. $this->filterDatagrid->setMaxPerPage($this->maxPerPage);
  348. // first pass, configure and normalize the filterFields array
  349. $this->filterDatagrid->setFilterFields($this->filterFields);
  350. $this->filterDatagrid->buildFilterFields();
  351. // update the current filterFields array and apply admin custom code
  352. $this->filterFields = $this->filterDatagrid->getFilterFields();
  353. $this->configureFilterFields();
  354. // set the final value to the datagrid
  355. $this->filterDatagrid->setFilterFields($this->filterFields);
  356. }
  357. return $this->filterDatagrid;
  358. }
  359. /**
  360. *
  361. */
  362. public function getRootCode()
  363. {
  364. return $this->getRoot()->getCode();
  365. }
  366. /**
  367. * return the master admin
  368. *
  369. */
  370. public function getRoot()
  371. {
  372. $parentFieldDescription = $this->getParentFieldDescription();
  373. if (!$parentFieldDescription) {
  374. return $this;
  375. }
  376. return $parentFieldDescription->getAdmin()->getRoot();
  377. }
  378. /**
  379. * Construct and build the form field definitions
  380. *
  381. * @return list form field definition
  382. */
  383. public function getFormFields()
  384. {
  385. $this->buildFormFields();
  386. return $this->formFields;
  387. }
  388. public function getListFields()
  389. {
  390. $this->buildListFields();
  391. return $this->listFields;
  392. }
  393. public function setBaseControllerName($baseControllerName)
  394. {
  395. $this->baseControllerName = $baseControllerName;
  396. }
  397. public function getBaseControllerName()
  398. {
  399. return $this->baseControllerName;
  400. }
  401. public function setBaseRoute($baseRoute)
  402. {
  403. $this->baseRoute = $baseRoute;
  404. }
  405. public function getBaseRoute()
  406. {
  407. return $this->baseRoute;
  408. }
  409. public function setConfigurationPool($configurationPool)
  410. {
  411. $this->configurationPool = $configurationPool;
  412. }
  413. public function getConfigurationPool()
  414. {
  415. return $this->configurationPool;
  416. }
  417. public function setCode($code)
  418. {
  419. $this->code = $code;
  420. }
  421. public function getCode()
  422. {
  423. return $this->code;
  424. }
  425. public function setLabel($label)
  426. {
  427. $this->label = $label;
  428. }
  429. public function getLabel()
  430. {
  431. return $this->label;
  432. }
  433. public function setFilterFields($filterFields)
  434. {
  435. $this->filterFields = $filterFields;
  436. }
  437. public function getFilterFields()
  438. {
  439. return $this->filterFields;
  440. }
  441. public function setMaxPerPage($maxPerPage)
  442. {
  443. $this->maxPerPage = $maxPerPage;
  444. }
  445. public function getMaxPerPage()
  446. {
  447. return $this->maxPerPage;
  448. }
  449. public function setFormGroups($formGroups)
  450. {
  451. $this->formGroups = $formGroups;
  452. }
  453. public function getFormGroups()
  454. {
  455. $this->buildFormGroups();
  456. return $this->formGroups;
  457. }
  458. public function setParentFieldDescription($parentFieldDescription)
  459. {
  460. $this->parentFieldDescription = $parentFieldDescription;
  461. }
  462. public function getParentFieldDescription()
  463. {
  464. return $this->parentFieldDescription;
  465. }
  466. public function setSubject($subject)
  467. {
  468. $this->subject = $subject;
  469. }
  470. public function getSubject()
  471. {
  472. return $this->subject;
  473. }
  474. }