PageRenderTime 61ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/Admin/BaseFieldDescription.php

https://github.com/helmer/SonataAdminBundle
PHP | 459 lines | 164 code | 53 blank | 242 comment | 7 complexity | 04114e9a49ab17174a5b2ad6a31c91ca MD5 | raw file
  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. * - field_type (o): the widget class to use to render the field
  35. * - 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. * - options (o): options given to the Filter object
  47. * - field_options (o): options given to the filter field object
  48. * - field_type (o): options given to the filter field object
  49. *
  50. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  51. */
  52. abstract class BaseFieldDescription implements FieldDescriptionInterface
  53. {
  54. /**
  55. * @var string the field name
  56. */
  57. protected $name;
  58. /**
  59. * @var string|integer the type
  60. */
  61. protected $type;
  62. /**
  63. * @var string|integer the original mapping type
  64. */
  65. protected $mappingType;
  66. /**
  67. * @var string the field name (of the form)
  68. */
  69. protected $fieldName;
  70. /**
  71. * @var array the Doctrine association mapping
  72. */
  73. protected $associationMapping;
  74. /**
  75. * @var array the Doctrine field information
  76. */
  77. protected $fieldMapping;
  78. /**
  79. * @var string the template name
  80. */
  81. protected $template;
  82. /**
  83. * @var array the option collection
  84. */
  85. protected $options = array();
  86. /**
  87. * @var Admin|null the parent Admin instance
  88. */
  89. protected $parent = null;
  90. /**
  91. * @var Admin the related admin instance
  92. */
  93. protected $admin;
  94. /**
  95. * @var Admin the associated admin class if the object is associated to another entity
  96. */
  97. protected $associationAdmin;
  98. /**
  99. * @var string the help message to display
  100. */
  101. protected $help;
  102. /**
  103. * set the field name
  104. *
  105. * @param string $fieldName
  106. * @return void
  107. */
  108. public function setFieldName($fieldName)
  109. {
  110. $this->fieldName = $fieldName;
  111. }
  112. /**
  113. * return the field name
  114. *
  115. * @return string the field name
  116. */
  117. public function getFieldName()
  118. {
  119. return $this->fieldName;
  120. }
  121. /**
  122. * Set the name
  123. *
  124. * @param string $name
  125. * @return void
  126. */
  127. public function setName($name)
  128. {
  129. $this->name = $name;
  130. if (!$this->getFieldName()) {
  131. $this->setFieldName($name);
  132. }
  133. }
  134. /**
  135. * Return the name, the name can be used as a form label or table header
  136. *
  137. * @return string the name
  138. */
  139. public function getName()
  140. {
  141. return $this->name;
  142. }
  143. /**
  144. * Return the value represented by the provided name
  145. *
  146. * @param string $name
  147. * @param null $default
  148. * @return array|null the value represented by the provided name
  149. */
  150. public function getOption($name, $default = null)
  151. {
  152. return isset($this->options[$name]) ? $this->options[$name] : $default;
  153. }
  154. /**
  155. * Define an option, an option is has a name and a value
  156. *
  157. * @param string $name
  158. * @param mixed $value
  159. * @return void set the option value
  160. */
  161. public function setOption($name, $value)
  162. {
  163. $this->options[$name] = $value;
  164. }
  165. /**
  166. * Define the options value, if the options array contains the reserved keywords
  167. * - type
  168. * - template
  169. *
  170. * Then the value are copied across to the related property value
  171. *
  172. * @param array $options
  173. * @return void
  174. */
  175. public function setOptions(array $options)
  176. {
  177. // set the type if provided
  178. if (isset($options['type'])) {
  179. $this->setType($options['type']);
  180. unset($options['type']);
  181. }
  182. // remove property value
  183. if (isset($options['template'])) {
  184. $this->setTemplate($options['template']);
  185. unset($options['template']);
  186. }
  187. $this->options = $options;
  188. }
  189. /**
  190. * return options
  191. *
  192. * @return array options
  193. */
  194. public function getOptions()
  195. {
  196. return $this->options;
  197. }
  198. /**
  199. * return the template used to render the field
  200. *
  201. * @param string $template
  202. * @return void
  203. */
  204. public function setTemplate($template)
  205. {
  206. $this->template = $template;
  207. }
  208. /**
  209. * return the template name
  210. *
  211. * @return string the template name
  212. */
  213. public function getTemplate()
  214. {
  215. return $this->template;
  216. }
  217. /**
  218. * return the field type, the type is a mandatory field as it used to select the correct template
  219. * or the logic associated to the current FieldDescription object
  220. *
  221. * @param string $type
  222. * @return void the field type
  223. */
  224. public function setType($type)
  225. {
  226. $this->type = $type;
  227. }
  228. /**
  229. * return the type
  230. *
  231. * @return int|string
  232. */
  233. public function getType()
  234. {
  235. return $this->type;
  236. }
  237. /**
  238. * set the parent Admin (only used in nested admin)
  239. *
  240. * @param \Sonata\AdminBundle\Admin\AdminInterface $parent
  241. * @return void
  242. */
  243. public function setParent(AdminInterface $parent)
  244. {
  245. $this->parent = $parent;
  246. }
  247. /**
  248. * return the parent Admin (only used in nested admin)
  249. *
  250. * @return \Sonata\AdminBundle\Admin\AdminInterface
  251. */
  252. public function getParent()
  253. {
  254. return $this->parent;
  255. }
  256. /**
  257. * return the association mapping definition
  258. *
  259. * @return array
  260. */
  261. public function getAssociationMapping()
  262. {
  263. return $this->associationMapping;
  264. }
  265. /**
  266. * return the field mapping definition
  267. *
  268. * @return array the field mapping definition
  269. */
  270. public function getFieldMapping()
  271. {
  272. return $this->fieldMapping;
  273. }
  274. /**
  275. * set the association admin instance (only used if the field is linked to an Admin)
  276. *
  277. * @param \Sonata\AdminBundle\Admin\AdminInterface $associationAdmin the associated admin
  278. */
  279. public function setAssociationAdmin(AdminInterface $associationAdmin)
  280. {
  281. $this->associationAdmin = $associationAdmin;
  282. $this->associationAdmin->setParentFieldDescription($this);
  283. }
  284. /**
  285. * return the associated Admin instance (only used if the field is linked to an Admin)
  286. * @return \Sonata\AdminBundle\Admin\AdminInterface
  287. */
  288. public function getAssociationAdmin()
  289. {
  290. return $this->associationAdmin;
  291. }
  292. /**
  293. *
  294. * @return boolean
  295. */
  296. public function hasAssociationAdmin()
  297. {
  298. return $this->associationAdmin !== null;
  299. }
  300. /**
  301. * return the value linked to the description
  302. *
  303. * @param $object
  304. * @return bool|mixed
  305. */
  306. public function getValue($object)
  307. {
  308. $camelizedFieldName = self::camelize($this->getFieldName());
  309. $getters = array();
  310. // prefer method name given in the code option
  311. if ($this->getOption('code')) {
  312. $getters[] = $this->getOption('code');
  313. }
  314. $getters[] = 'get'.$camelizedFieldName;
  315. $getters[] = 'is'.$camelizedFieldName;
  316. foreach ($getters as $getter) {
  317. if (method_exists($object, $getter)) {
  318. return call_user_func(array($object, $getter));
  319. }
  320. }
  321. throw new NoValueException(sprintf('Unable to retrieve the value of `%s`', $this->getName()));
  322. }
  323. /**
  324. * set the admin class linked to this FieldDescription
  325. *
  326. * @param \Sonata\AdminBundle\Admin\AdminInterface $admin
  327. * @return void
  328. */
  329. public function setAdmin(AdminInterface $admin)
  330. {
  331. $this->admin = $admin;
  332. }
  333. /**
  334. * @return \Sonata\AdminBundle\Admin\AdminInterface the admin class linked to this FieldDescription
  335. */
  336. public function getAdmin()
  337. {
  338. return $this->admin;
  339. }
  340. /**
  341. * merge option values related to the provided option name
  342. *
  343. * @throws \RuntimeException
  344. * @param string $name
  345. * @param array $options
  346. * @return void
  347. */
  348. public function mergeOption($name, array $options = array())
  349. {
  350. if (!isset($this->options[$name])) {
  351. $this->options[$name] = array();
  352. }
  353. if (!is_array($this->options[$name])) {
  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_recursive($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. }