Form collection preset data not based on entity - symfony

I have a difficult problem to solve. I need to implement a functionality to create custom forms (that is declare what fields it should have) and then be able to save and retrieve the data. The form generation mechanism is based on EAV model - form template entity has form fields entity (which are form templates attributes). Each form field has type, name, label etc.
Then I dynamically display the form( foreach $fields as $field (...) $formBuilder->add($field->getType() etc.). After all that the data is saved in another entity called FormInstanceData which consist of field name:field value pairs.
The hard part is that I have to be able to create form templates with form field groups which behave like collections (new ones can be added with JS). The form (generated with the template) displays correctly, but I have problem with retrieving the data (as the final data is not an entity for obvious reasons). Simple fields can be successfully filled out with retrieved data (by passing data option with the field name as key), but I can't get the nested collection fields to work - even after passing the data, the collections simply don't display.
The part of the code responsible for that looks like this:
elseif ($fieldType === 'collection'){
$subfields = $field->getSubfields();
$formBuilder->add('subfields', 'collection', array(
'type' => new FormCollectionType($subfields),
'allow_add' => true,
'mapped' => false,
'allow_delete' => true,
'by_reference' => false,
'options' => array('required' => false, 'data' => array(
array('title' => 'lorem', 'subtitle' => 'ipsum'),
array('title' => 'lorem', 'subtitle' => 'ipsum')
The FormCollectionType is also generated dynamically with the $subfields parameter. In this case, each item in collection has two fields - title and subtitle. With the data I passed, two already filled out input groups should appear, but nothing does. You can still add new (empty) groups with JS.
Please advise.

Ok, turned out the data needs to be passed not as:
'options' => array('required' => false, 'data' => array(
array('title' => 'lorem', 'subtitle' => 'ipsum'),
array('title' => 'lorem', 'subtitle' => 'ipsum')
but:
'data' => array(
array('title' => 'lorem', 'subtitle' => 'ipsum'),
array('title' => 'lorem', 'subtitle' => 'ipsum')

Related

Is there custom validation of meta values in Wordpress REST API?

WordPress allows registering meta values in the REST API through register_meta().
One can add a schema to the meta like so:
register_meta(
'user',
'my_meta_key',
array(
'type' => 'array',
'description' => 'This is my array meta key!',
'single' => true,
'show_in_rest' => array(
'schema' => array(
'type' => 'array',
'items' => array(
'type' => 'string',
'format' => 'date-time',
),
),
),
)
);
It took me some time to find out about the 'format' => 'date-time' option.
I would like to validate my meta fields myself (for a custom post-type). But it seems like the WP_REST_Posts_Controller uses get_endpoint_args_for_item_schema() to set up the schema for arguments in register_rest_route().
register_rest_route() would allow for a custom validate_callback, but rest_get_endpoint_args_for_schema() hard-codes it to rest_validate_request_arg(), which uses rest_validate_value_from_schema().
And there are the primitives and hard-coded formats hex-color, date-time, email, ip and uuid.
So there are two options I see:
Live with it. Just accept the validating against schema primitives, since the schema is only validated on REST requests.
Extend WP_REST_Posts_Controller just to sneak in my own get_endpoint_args_for_item_schema(), which adds an exception for my meta key.
Do you have another idea, how to solve this issue?
EDIT: There seems to be a pattern property for strings. So I could at least do something like (don't mind the regex itself):
'schema' => array(
'type' => 'string',
'pattern' => '[0-9]/[0-9]^$',
),

Drupal 7 creating a custom entity

I'm trying to make a form with some fields and save the values in Drupal 7 where every user can enter their data. I tried creating a custom entity with an existing database table like so:
function bank_info_entity_info() {
return array(
'bank_info' => array(
'label' => t('BankInfo'),
'entity class' => 'Entity',
'base table' => 'bank_info',
'field_ui_base_route'=> 'banking',
'controller class' => 'EntityAPIController',
'fieldable' => TRUE,
'entity keys' => array(
'id' => 'user_uid',
'"bundle"' => 'bank_info',
),
// Use the default label() and uri() functions
'label callback' => 'entity_class_label',
'uri callback' => 'entity_class_uri',
//'module' => 'bank_info',
),
);
}
and I keep getting this error:
array_keys() expects parameter 1 to be array, null given common.inc:7334
PHP Warning: Invalid argument supplied for foreach() in /var/www/html/includes/common.inc on line 7314
when I run the command:
drupal_get_schema('bank_info')
It returns false which causes that error.
Any ideas?

Drupal: how do I retrieve the select type values from a module Config form?

I'm new to Drupal and am trying to build a module. Part of what this module does is allow you to add preset classes from a drop down field.
For the most part I've got this working but for one thing: I seem to only be able to retrieve the select options name, not it's value.
The code I have is below.
In the config form creation function I have:
$styles = array(
'None' => '',
'Blue Buttons' => 'btn blue-btn',
'Red Buttons' => 'btn red-btn',
);
$mymodule_form['style'] = array(
'#type' => 'select',
'#required' => TRUE,
'#title' => t('Style'),
'#description' => t('Style for buttons'),
'#default_value' => $form_values['style'],
'#empty_option' => t('- Select -'),
'#options' => drupal_map_assoc(array_keys($styles)),
);
But, when I run dpm($this->options['style']); later on in my code when I want to use those styles, I get the key names return (eg Button Red)
Would anyone know how I can retrieve the values?
I was using drupal_map_assoc when I didn't need to.
'#options' => $styles,
is fine.
(Also, I had my key names and values around the wrong way).

Symfony2 form collection with custom labels

I have an object - Book with Persons collection inside (each person has name property) and I need to create a form type persons it is a collection simply checkbox but I would like to have as a label on each checkbox persons name how to do it ?
I have BookType:
$builder->add('persons', 'collection', array(
'type' => 'checkbox',
'options' => array(
'required' => false,
),
));
How to add label with persons name ??
I'm not sure if I understood your question, but I'll try to help you anyway.
Did you already tried this?
$builder->add('persons','entity', array(
'class' => 'VendorBundle:Entity',
'property' => 'name',
'label' => 'YourLabel'
))
(Adapt the code for your configurations by changing 'VendorBundle:Entity' and 'YourLabel' )
This adds a field in your form which has the 'property name' of each 'VendorBundle:Person' and has a label 'YourLabel' right before the dropdown field.

How to add two sonata_type_collection fields of the same property in the same admin?

Suppose you have ArticleAdmin and CommentsAdmin. It is easy to add one-to-many editing in Sonata:
$formMapper->add('comments', 'sonata_type_collection',
array(
'by_reference' => false,
),
array(
'edit' => 'inline',
'inline' => 'table',
)
);
However, suppose I have more complicated CommentsAdmin form and it can has two visualizations depending on the kind of comment in it. I would like to display two sonata_type_collection fields in ArticleAdmin for grouping different types of comments into two different edit tables.
Adding another add('comments', ...) is of course incorrect, and adding add('comments2', ...) results in exception.
I will manage separating comments between two fields in admin, but how to create sonata_type_collection field on a virtual entity field Article::comments2? How to tell Sonata Admin what kind of collection should it be?
I'm not sure if this will help you but:
->add('categoryHasMedia', 'sonata_type_collection', array(
'cascade_validation' => true,
'label' => 'Logo\'s'
), array(
'edit' => 'inline',
'inline' => 'table',
'link_parameters' => array('context' => $context),
'admin_code' => 'appstrakt.project.admin.category_has_media',
))
By using admin_code you can tell which admin class you want to use for that sonata_type_collection if I'm not mistaken.

Resources