BaseFieldDescription.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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. * @var string the help message to display
  96. */
  97. protected $help;
  98. /**
  99. * set the field name
  100. *
  101. * @param string $fieldName
  102. * @return void
  103. */
  104. public function setFieldName($fieldName)
  105. {
  106. $this->fieldName = $fieldName;
  107. }
  108. /**
  109. * return the field name
  110. *
  111. * @return string the field name
  112. */
  113. public function getFieldName()
  114. {
  115. return $this->fieldName;
  116. }
  117. /**
  118. * Set the name
  119. *
  120. * @param string $name
  121. * @return void
  122. */
  123. public function setName($name)
  124. {
  125. $this->name = $name;
  126. if (!$this->getFieldName()) {
  127. $this->setFieldName($name);
  128. }
  129. }
  130. /**
  131. * Return the name, the name can be used as a form label or table header
  132. *
  133. * @return string the name
  134. */
  135. public function getName()
  136. {
  137. return $this->name;
  138. }
  139. /**
  140. * Return the value represented by the provided name
  141. *
  142. * @param string $name
  143. * @param null $default
  144. * @return array|null the value represented by the provided name
  145. */
  146. public function getOption($name, $default = null)
  147. {
  148. return isset($this->options[$name]) ? $this->options[$name] : $default;
  149. }
  150. /**
  151. * Define an option, an option is has a name and a value
  152. *
  153. * @param string $name
  154. * @param mixed $value
  155. * @return void set the option value
  156. */
  157. public function setOption($name, $value)
  158. {
  159. $this->options[$name] = $value;
  160. }
  161. /**
  162. * Define the options value, if the options array contains the reserved keywords
  163. * - type
  164. * - template
  165. *
  166. * Then the value are copied across to the related property value
  167. *
  168. * @param array $options
  169. * @return void
  170. */
  171. public function setOptions(array $options)
  172. {
  173. // set the type if provided
  174. if (isset($options['type'])) {
  175. $this->setType($options['type']);
  176. unset($options['type']);
  177. }
  178. // remove property value
  179. if (isset($options['template'])) {
  180. $this->setTemplate($options['template']);
  181. unset($options['template']);
  182. }
  183. $this->options = $options;
  184. }
  185. /**
  186. * return options
  187. *
  188. * @return array options
  189. */
  190. public function getOptions()
  191. {
  192. return $this->options;
  193. }
  194. /**
  195. * return the template used to render the field
  196. *
  197. * @param string $template
  198. * @return void
  199. */
  200. public function setTemplate($template)
  201. {
  202. $this->template = $template;
  203. }
  204. /**
  205. * return the template name
  206. *
  207. * @return string the template name
  208. */
  209. public function getTemplate()
  210. {
  211. return $this->template;
  212. }
  213. /**
  214. * return the field type, the type is a mandatory field as it used to select the correct template
  215. * or the logic associated to the current FieldDescription object
  216. *
  217. * @param string $type
  218. * @return void the field type
  219. */
  220. public function setType($type)
  221. {
  222. $this->type = $type;
  223. }
  224. /**
  225. * return the type
  226. *
  227. * @return int|string
  228. */
  229. public function getType()
  230. {
  231. return $this->type;
  232. }
  233. /**
  234. * set the parent Admin (only used in nested admin)
  235. *
  236. * @param \Sonata\AdminBundle\Admin\AdminInterface $parent
  237. * @return void
  238. */
  239. public function setParent(AdminInterface $parent)
  240. {
  241. $this->parent = $parent;
  242. }
  243. /**
  244. * return the parent Admin (only used in nested admin)
  245. *
  246. * @return \Sonata\AdminBundle\Admin\AdminInterface
  247. */
  248. public function getParent()
  249. {
  250. return $this->parent;
  251. }
  252. /**
  253. * return the association mapping definition
  254. *
  255. * @return array
  256. */
  257. public function getAssociationMapping()
  258. {
  259. return $this->associationMapping;
  260. }
  261. /**
  262. * return the field mapping definition
  263. *
  264. * @return array the field mapping definition
  265. */
  266. public function getFieldMapping()
  267. {
  268. return $this->fieldMapping;
  269. }
  270. /**
  271. * set the association admin instance (only used if the field is linked to an Admin)
  272. *
  273. * @param \Sonata\AdminBundle\Admin\AdminInterface $associationAdmin the associated admin
  274. */
  275. public function setAssociationAdmin(AdminInterface $associationAdmin)
  276. {
  277. $this->associationAdmin = $associationAdmin;
  278. $this->associationAdmin->setParentFieldDescription($this);
  279. }
  280. /**
  281. * return the associated Admin instance (only used if the field is linked to an Admin)
  282. * @return \Sonata\AdminBundle\Admin\AdminInterface
  283. */
  284. public function getAssociationAdmin()
  285. {
  286. return $this->associationAdmin;
  287. }
  288. /**
  289. *
  290. * @return boolean
  291. */
  292. public function hasAssociationAdmin()
  293. {
  294. return $this->associationAdmin !== null;
  295. }
  296. /**
  297. * return the value linked to the description
  298. *
  299. * @param $object
  300. * @return bool|mixed
  301. */
  302. public function getValue($object)
  303. {
  304. $camelizedFieldName = self::camelize($this->getFieldName());
  305. $getters = array(
  306. 'get'.$camelizedFieldName,
  307. 'is'.$camelizedFieldName,
  308. );
  309. if ($this->getOption('code')) {
  310. $getters[] = $this->getOption('code');
  311. }
  312. foreach ($getters as $getter) {
  313. if (method_exists($object, $getter)) {
  314. return call_user_func(array($object, $getter));
  315. }
  316. }
  317. throw new NoValueException();
  318. }
  319. /**
  320. * set the admin class linked to this FieldDescription
  321. *
  322. * @param \Sonata\AdminBundle\Admin\AdminInterface $admin
  323. * @return void
  324. */
  325. public function setAdmin(AdminInterface $admin)
  326. {
  327. $this->admin = $admin;
  328. }
  329. /**
  330. * @return \Sonata\AdminBundle\Admin\AdminInterface the admin class linked to this FieldDescription
  331. */
  332. public function getAdmin()
  333. {
  334. return $this->admin;
  335. }
  336. /**
  337. * merge option values related to the provided option name
  338. *
  339. * @throws \RuntimeException
  340. * @param string $name
  341. * @param array $options
  342. * @return void
  343. */
  344. public function mergeOption($name, array $options = array())
  345. {
  346. if (!isset($this->options[$name])) {
  347. $this->options[$name] = array();
  348. }
  349. if (!is_array($this->options[$name]))
  350. {
  351. throw new \RuntimeException(sprintf('The key `%s` does not point to an array value', $name));
  352. }
  353. $this->options[$name] = array_merge($this->options[$name], $options);
  354. }
  355. /**
  356. * merge options values
  357. *
  358. * @param array $options
  359. * @return void
  360. */
  361. public function mergeOptions(array $options = array())
  362. {
  363. $this->setOptions(array_merge($this->options, $options));
  364. }
  365. /**
  366. * set the original mapping type (only used if the field is linked to an entity)
  367. *
  368. * @param string|int $mappingType
  369. * @return void
  370. */
  371. public function setMappingType($mappingType)
  372. {
  373. $this->mappingType = $mappingType;
  374. }
  375. /**
  376. * return the mapping type
  377. *
  378. * @return int|string
  379. */
  380. public function getMappingType()
  381. {
  382. return $this->mappingType;
  383. }
  384. /**
  385. * Camelize a string
  386. *
  387. * @static
  388. * @param string $property
  389. * @return string
  390. */
  391. public static function camelize($property)
  392. {
  393. return preg_replace(array('/(^|_| )+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $property);
  394. }
  395. public function setHelp($help)
  396. {
  397. $this->help = $help;
  398. }
  399. public function getHelp()
  400. {
  401. return $this->help;
  402. }
  403. }