BaseFieldDescription.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) 2010-2011 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 Sonata\AdminBundle\Admin;
  11. use Sonata\AdminBundle\Admin\AdminInterface;
  12. /**
  13. * A FieldDescription hold the information about a field. A typical
  14. * admin instance contains different collections of fields
  15. *
  16. * - form: used by the form
  17. * - list: used by the list
  18. * - filter: used by the list filter
  19. *
  20. * Some options are global across the different contexts, other are
  21. * context specifics.
  22. *
  23. * Global options :
  24. * - type (m): define the field type (use to tweak the form or the list)
  25. * - template (o) : the template used to render the field
  26. * - name (o) : the name used (label in the form, title in the list)
  27. * - link_parameters (o) : add link parameter to the related Admin class when
  28. * the Admin.generateUrl is called
  29. * - code : the method name to retrieve the related value
  30. * - associated_tostring : the method to retrieve the "string" representation
  31. * of the collection element.
  32. *
  33. * Form Field options :
  34. * - form_field_type (o): the widget class to use to render the field
  35. * - form_field_options (o): the options to give to the widget
  36. * - edit (o) : list|inline|standard (only used for associated admin)
  37. * - list : open a popup where the user can search, filter and click on one field
  38. * to select one item
  39. * - inline : the associated form admin is embedded into the current form
  40. * - standard : the associated admin is created through a popup
  41. *
  42. * List Field options :
  43. * - identifier (o): if set to true a link appear on to edit the element
  44. *
  45. * Filter Field options :
  46. * - filter_options (o): options given to the Filter object
  47. * - filter_field_options (o): options given to the filter field object
  48. *
  49. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  50. */
  51. abstract class BaseFieldDescription implements FieldDescriptionInterface
  52. {
  53. /**
  54. * @var string the field name
  55. */
  56. protected $name;
  57. /**
  58. * @var string|integer the type
  59. */
  60. protected $type;
  61. /**
  62. * @var string|integer the original mapping type
  63. */
  64. protected $mappingType;
  65. /**
  66. * @var string the field name (of the form)
  67. */
  68. protected $fieldName;
  69. /**
  70. * @var array the Doctrine association mapping
  71. */
  72. protected $associationMapping;
  73. /**
  74. * @var array the Doctrine field information
  75. */
  76. protected $fieldMapping;
  77. /**
  78. * @var string the template name
  79. */
  80. protected $template;
  81. /**
  82. * @var array the option collection
  83. */
  84. protected $options = array();
  85. /**
  86. * @var Admin|null the parent Admin instance
  87. */
  88. protected $parent = null;
  89. /**
  90. * @var Admin the related admin instance
  91. */
  92. protected $admin;
  93. /**
  94. * @var Admin the associated admin class if the object is associated to another entity
  95. */
  96. protected $associationAdmin;
  97. /**
  98. * @var string the help message to display
  99. */
  100. protected $help;
  101. /**
  102. * set the field name
  103. *
  104. * @param string $fieldName
  105. * @return void
  106. */
  107. public function setFieldName($fieldName)
  108. {
  109. $this->fieldName = $fieldName;
  110. }
  111. /**
  112. * return the field name
  113. *
  114. * @return string the field name
  115. */
  116. public function getFieldName()
  117. {
  118. return $this->fieldName;
  119. }
  120. /**
  121. * Set the name
  122. *
  123. * @param string $name
  124. * @return void
  125. */
  126. public function setName($name)
  127. {
  128. $this->name = $name;
  129. if (!$this->getFieldName()) {
  130. $this->setFieldName($name);
  131. }
  132. }
  133. /**
  134. * Return the name, the name can be used as a form label or table header
  135. *
  136. * @return string the name
  137. */
  138. public function getName()
  139. {
  140. return $this->name;
  141. }
  142. /**
  143. * Return the value represented by the provided name
  144. *
  145. * @param string $name
  146. * @param null $default
  147. * @return array|null the value represented by the provided name
  148. */
  149. public function getOption($name, $default = null)
  150. {
  151. return isset($this->options[$name]) ? $this->options[$name] : $default;
  152. }
  153. /**
  154. * Define an option, an option is has a name and a value
  155. *
  156. * @param string $name
  157. * @param mixed $value
  158. * @return void set the option value
  159. */
  160. public function setOption($name, $value)
  161. {
  162. $this->options[$name] = $value;
  163. }
  164. /**
  165. * Define the options value, if the options array contains the reserved keywords
  166. * - type
  167. * - template
  168. *
  169. * Then the value are copied across to the related property value
  170. *
  171. * @param array $options
  172. * @return void
  173. */
  174. public function setOptions(array $options)
  175. {
  176. // set the type if provided
  177. if (isset($options['type'])) {
  178. $this->setType($options['type']);
  179. unset($options['type']);
  180. }
  181. // remove property value
  182. if (isset($options['template'])) {
  183. $this->setTemplate($options['template']);
  184. unset($options['template']);
  185. }
  186. $this->options = $options;
  187. }
  188. /**
  189. * return options
  190. *
  191. * @return array options
  192. */
  193. public function getOptions()
  194. {
  195. return $this->options;
  196. }
  197. /**
  198. * return the template used to render the field
  199. *
  200. * @param string $template
  201. * @return void
  202. */
  203. public function setTemplate($template)
  204. {
  205. $this->template = $template;
  206. }
  207. /**
  208. * return the template name
  209. *
  210. * @return string the template name
  211. */
  212. public function getTemplate()
  213. {
  214. return $this->template;
  215. }
  216. /**
  217. * return the field type, the type is a mandatory field as it used to select the correct template
  218. * or the logic associated to the current FieldDescription object
  219. *
  220. * @param string $type
  221. * @return void the field type
  222. */
  223. public function setType($type)
  224. {
  225. $this->type = $type;
  226. }
  227. /**
  228. * return the type
  229. *
  230. * @return int|string
  231. */
  232. public function getType()
  233. {
  234. return $this->type;
  235. }
  236. /**
  237. * set the parent Admin (only used in nested admin)
  238. *
  239. * @param \Sonata\AdminBundle\Admin\AdminInterface $parent
  240. * @return void
  241. */
  242. public function setParent(AdminInterface $parent)
  243. {
  244. $this->parent = $parent;
  245. }
  246. /**
  247. * return the parent Admin (only used in nested admin)
  248. *
  249. * @return \Sonata\AdminBundle\Admin\AdminInterface
  250. */
  251. public function getParent()
  252. {
  253. return $this->parent;
  254. }
  255. /**
  256. * return the association mapping definition
  257. *
  258. * @return array
  259. */
  260. public function getAssociationMapping()
  261. {
  262. return $this->associationMapping;
  263. }
  264. /**
  265. * return the field mapping definition
  266. *
  267. * @return array the field mapping definition
  268. */
  269. public function getFieldMapping()
  270. {
  271. return $this->fieldMapping;
  272. }
  273. /**
  274. * set the association admin instance (only used if the field is linked to an Admin)
  275. *
  276. * @param \Sonata\AdminBundle\Admin\AdminInterface $associationAdmin the associated admin
  277. */
  278. public function setAssociationAdmin(AdminInterface $associationAdmin)
  279. {
  280. $this->associationAdmin = $associationAdmin;
  281. $this->associationAdmin->setParentFieldDescription($this);
  282. }
  283. /**
  284. * return the associated Admin instance (only used if the field is linked to an Admin)
  285. * @return \Sonata\AdminBundle\Admin\AdminInterface
  286. */
  287. public function getAssociationAdmin()
  288. {
  289. return $this->associationAdmin;
  290. }
  291. /**
  292. *
  293. * @return boolean
  294. */
  295. public function hasAssociationAdmin()
  296. {
  297. return $this->associationAdmin !== null;
  298. }
  299. /**
  300. * return the value linked to the description
  301. *
  302. * @param $object
  303. * @return bool|mixed
  304. */
  305. public function getValue($object)
  306. {
  307. $camelizedFieldName = self::camelize($this->getFieldName());
  308. $getters = array();
  309. // prefer method name given in the code option
  310. if ($this->getOption('code')) {
  311. $getters[] = $this->getOption('code');
  312. }
  313. $getters[] = 'get'.$camelizedFieldName;
  314. $getters[] = 'is'.$camelizedFieldName;
  315. foreach ($getters as $getter) {
  316. if (method_exists($object, $getter)) {
  317. return call_user_func(array($object, $getter));
  318. }
  319. }
  320. throw new NoValueException();
  321. }
  322. /**
  323. * set the admin class linked to this FieldDescription
  324. *
  325. * @param \Sonata\AdminBundle\Admin\AdminInterface $admin
  326. * @return void
  327. */
  328. public function setAdmin(AdminInterface $admin)
  329. {
  330. $this->admin = $admin;
  331. }
  332. /**
  333. * @return \Sonata\AdminBundle\Admin\AdminInterface the admin class linked to this FieldDescription
  334. */
  335. public function getAdmin()
  336. {
  337. return $this->admin;
  338. }
  339. /**
  340. * merge option values related to the provided option name
  341. *
  342. * @throws \RuntimeException
  343. * @param string $name
  344. * @param array $options
  345. * @return void
  346. */
  347. public function mergeOption($name, array $options = array())
  348. {
  349. if (!isset($this->options[$name])) {
  350. $this->options[$name] = array();
  351. }
  352. if (!is_array($this->options[$name]))
  353. {
  354. throw new \RuntimeException(sprintf('The key `%s` does not point to an array value', $name));
  355. }
  356. $this->options[$name] = array_merge($this->options[$name], $options);
  357. }
  358. /**
  359. * merge options values
  360. *
  361. * @param array $options
  362. * @return void
  363. */
  364. public function mergeOptions(array $options = array())
  365. {
  366. $this->setOptions(array_merge($this->options, $options));
  367. }
  368. /**
  369. * set the original mapping type (only used if the field is linked to an entity)
  370. *
  371. * @param string|int $mappingType
  372. * @return void
  373. */
  374. public function setMappingType($mappingType)
  375. {
  376. $this->mappingType = $mappingType;
  377. }
  378. /**
  379. * return the mapping type
  380. *
  381. * @return int|string
  382. */
  383. public function getMappingType()
  384. {
  385. return $this->mappingType;
  386. }
  387. /**
  388. * Camelize a string
  389. *
  390. * @static
  391. * @param string $property
  392. * @return string
  393. */
  394. public static function camelize($property)
  395. {
  396. return preg_replace(array('/(^|_| )+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
  397. }
  398. public function setHelp($help)
  399. {
  400. $this->help = $help;
  401. }
  402. public function getHelp()
  403. {
  404. return $this->help;
  405. }
  406. }