* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Sonata\AdminBundle\Admin; use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\AdminBundle\Exception\NoValueException; /** * A FieldDescription hold the information about a field. A typical * admin instance contains different collections of fields * * - form: used by the form * - list: used by the list * - filter: used by the list filter * * Some options are global across the different contexts, other are * context specifics. * * Global options : * - type (m): define the field type (use to tweak the form or the list) * - template (o) : the template used to render the field * - name (o) : the name used (label in the form, title in the list) * - link_parameters (o) : add link parameter to the related Admin class when * the Admin.generateUrl is called * - code : the method name to retrieve the related value * - associated_tostring : the method to retrieve the "string" representation * of the collection element. * * Form Field options : * - field_type (o): the widget class to use to render the field * - field_options (o): the options to give to the widget * - edit (o) : list|inline|standard (only used for associated admin) * - list : open a popup where the user can search, filter and click on one field * to select one item * - inline : the associated form admin is embedded into the current form * - standard : the associated admin is created through a popup * * List Field options : * - identifier (o): if set to true a link appear on to edit the element * * Filter Field options : * - options (o): options given to the Filter object * - field_options (o): options given to the filter field object * - field_type (o): options given to the filter field object * * @author Thomas Rabaix */ abstract class BaseFieldDescription implements FieldDescriptionInterface { /** * @var string the field name */ protected $name; /** * @var string|integer the type */ protected $type; /** * @var string|integer the original mapping type */ protected $mappingType; /** * @var string the field name (of the form) */ protected $fieldName; /** * @var array the ORM association mapping */ protected $associationMapping; /** * @var array the ORM field information */ protected $fieldMapping; /* * var array the ORM parent mapping association */ protected $parentAssociationMappings; /** * @var string the template name */ protected $template; /** * @var array the option collection */ protected $options = array(); /** * @var Admin|null the parent Admin instance */ protected $parent = null; /** * @var Admin the related admin instance */ protected $admin; /** * @var Admin the associated admin class if the object is associated to another entity */ protected $associationAdmin; /** * @var string the help message to display */ protected $help; /** * {@inheritdoc} */ public function setFieldName($fieldName) { $this->fieldName = $fieldName; } /** * {@inheritdoc} */ public function getFieldName() { return $this->fieldName; } /** * {@inheritdoc} */ public function setName($name) { $this->name = $name; if (!$this->getFieldName()) { $this->setFieldName(substr(strrchr('.' . $name, '.'), 1)); } } /** * {@inheritdoc} */ public function getName() { return $this->name; } /** * {@inheritdoc} */ public function getOption($name, $default = null) { return isset($this->options[$name]) ? $this->options[$name] : $default; } /** * {@inheritdoc} */ public function setOption($name, $value) { $this->options[$name] = $value; } /** * {@inheritdoc} */ public function setOptions(array $options) { // set the type if provided if (isset($options['type'])) { $this->setType($options['type']); unset($options['type']); } // remove property value if (isset($options['template'])) { $this->setTemplate($options['template']); unset($options['template']); } // set help if provided if (isset($options['help'])) { $this->setHelp($options['help']); unset($options['help']); } $this->options = $options; } /** * {@inheritdoc} */ public function getOptions() { return $this->options; } /** * {@inheritdoc} */ public function setTemplate($template) { $this->template = $template; } /** * {@inheritdoc} */ public function getTemplate() { return $this->template; } /** * {@inheritdoc} */ public function setType($type) { $this->type = $type; } /** * {@inheritdoc} */ public function getType() { return $this->type; } /** * {@inheritdoc} */ public function setParent(AdminInterface $parent) { $this->parent = $parent; } /** * {@inheritdoc} */ public function getParent() { return $this->parent; } /** * {@inheritdoc} */ public function getAssociationMapping() { return $this->associationMapping; } /** * {@inheritdoc} */ public function getFieldMapping() { return $this->fieldMapping; } /** * {@inheritdoc} */ public function getParentAssociationMappings() { return $this->parentAssociationMappings; } /** * {@inheritdoc} */ public function setAssociationAdmin(AdminInterface $associationAdmin) { $this->associationAdmin = $associationAdmin; $this->associationAdmin->setParentFieldDescription($this); } /** * {@inheritdoc} */ public function getAssociationAdmin() { return $this->associationAdmin; } /** * {@inheritdoc} */ public function hasAssociationAdmin() { return $this->associationAdmin !== null; } /** * {@inheritdoc} */ public function getFieldValue($object, $fieldName) { $camelizedFieldName = self::camelize($fieldName); $getters = array(); // prefer method name given in the code option if ($this->getOption('code')) { $getters[] = $this->getOption('code'); } $getters[] = 'get' . $camelizedFieldName; $getters[] = 'is' . $camelizedFieldName; foreach ($getters as $getter) { if (method_exists($object, $getter)) { return call_user_func(array($object, $getter)); } } throw new NoValueException(sprintf('Unable to retrieve the value of `%s`', $this->getName())); } /** * {@inheritdoc} */ public function setAdmin(AdminInterface $admin) { $this->admin = $admin; } /** * {@inheritdoc} */ public function getAdmin() { return $this->admin; } /** * {@inheritdoc} */ public function mergeOption($name, array $options = array()) { if (!isset($this->options[$name])) { $this->options[$name] = array(); } if (!is_array($this->options[$name])) { throw new \RuntimeException(sprintf('The key `%s` does not point to an array value', $name)); } $this->options[$name] = array_merge($this->options[$name], $options); } /** * {@inheritdoc} */ public function mergeOptions(array $options = array()) { $this->setOptions(array_merge_recursive($this->options, $options)); } /** * {@inheritdoc} */ public function setMappingType($mappingType) { $this->mappingType = $mappingType; } /** * {@inheritdoc} */ public function getMappingType() { return $this->mappingType; } /** * Camelize a string * * @static * * @param string $property * * @return string */ public static function camelize($property) { return preg_replace_callback('/(^|[_. ])+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '') . strtoupper($match[2]); }, $property); } /** * Defines the help message * * @param string $help */ public function setHelp($help) { $this->help = $help; } /** * {@inheritdoc} */ public function getHelp() { return $this->help; } /** * {@inheritdoc} */ public function getLabel() { return $this->getOption('label'); } /** * {@inheritdoc} */ public function isSortable() { return $this->getOption('sortable', false); } /** * {@inheritdoc} */ public function getSortFieldMapping() { return $this->getOption('sort_field_mapping'); } /** * {@inheritdoc} */ public function getSortParentAssociationMapping() { return $this->getOption('sort_parent_association_mappings'); } }