BaseFieldDescription.php 10 KB

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