How to hide Date of birth field in overriden form? - drupal

In my hook form alter, this is the date of birth array:
[Birthdate] => Array(
[#type] => fieldset
[#title] => Birthdate
[#weight] => 1
[profile_birthdate] => Array(
[#type] => date
[#title] => Birthdate
[#default_value] =>
[#description] => The content of this field is kept private and will not be shown publicly.
[#required] => 1
)
)
I have tried:
unset($form['Birthdate']['profile_birthdate']);
unset($form['Birthdate']);
and that does not work as I still get the "Please enter a valid date of birth" message. I want the field hidden and no message.

The phrasing of the error message ('... a valid date...') hints on this being issued from a form validation function. Depending on how that is written, it might still try to validate the field, even if you removed it successfully from the form.
If that is the case, you'll need to either override the validation function with a custom version that does not expect the birthdate field (check the content of $form['#validate'] in your hook_form_alter() implementation). Alternatively, instead of removing the field, you could turn it into '#type' => 'hidden' or '#type' => 'value', and provide a default value that passes validation, but then you'll end up assigning bogus birth dates, which might not be what you want.

Related

Date format corrupted in sub fields when copying an ACF field

I've created a CPT to store a show calendar.
An ACF field calendar has been created to store places and dates of the shows. It is a repeater composed by 2 subfields: date (type=date) and city (type=select).
When I'm trying to copy the "calendar" field from one post to another, using
update_field( 'calendar', get_field( 'calendar', $id_post_origin ), $id_post_destination );
the dates are corrupted.
I've tried to run a delete_field() before but the result isn't better.
e.g. if my original post is:
0 =>
array (size=2)
'city' => string 'Vesoul' (length=6)
'date' => string '02/09/2019' (length=10)
the destination post will be after copying:
0 =>
array (size=2)
'city' => string 'Vesoul' (length=6)
'date' => string '09/02/2019' (length=10)
Is it possible to specify a date format? To duplicate a field without modifying it?
Thank you
As specified by Kenny from ACF support,
The get_field() function contains a formatting parameter that you set to false in order to return the raw database value. In the case of the date field, the unformated string would be in YYYYMMD format.
The ACF get_field() manual describes this $format_value parameter and provide an example to "Get a value without formatting".
In my case, the solution was to edit the get_field() call like this:
$dates = get_field( 'calendar', $id_post_origin, false ); // false to retrieve raw data
update_field( 'calendar', $dates, $id_post_destination );

How to convert an integer based entity field into a human readable name in Twig

In a Symfony 2.4+ project, what is the best way to register an array of values for a field that saves as an integer but needs to display human readable values in a template?
I have an entity with a property that is populated with integer values that represent different constant values:
/**
* The repetition frequency for billing cycle:
* #ORM\Column(type="smallint")
*/
protected $repetition = 0;
I would like to store the names of these values somewhere, so initially I put them in my entity with a getter:
protected $repetitionName = array(
0 => 'Setup',
1 => 'Second',
2 => 'Minute',
3 => 'Hour',
4 => 'Day',
5 => 'Week',
6 => 'Month',
7 => 'Year'
);
public function getRepetitionName() {
return $this->repetitionName;
}
This seems like a great central repository for the values.
Then in my twig template I don't want to display the integer, I want the corresponding name value. So I translate them like this:
<div class="billingCycle">{{ entity.repetitionName[entity.repetition] }}</div>
And in my form builder I make a field that references that array like this:
$builder->add('repetition', 'choice', array(
'label' => 'Billing Cycle',
'help' => 'The repetition frequency when this service is billed.',
'choices' => $builder->getData()->getRepetitionNamePer(),
// default to monthly (the most common)
'empty_data' => 6,
'required' => TRUE
));
The Problems With This Approach
1. Translation: If I want to translate this at any point, it's hard coded in one place.
2. Reusability: If I have other entities that have repetition (e.g. event calendar) it would be nice to reuse this.
3. Configurability: Ideally these would be editable in a config file instead of the entity code.
Alternative Solution: Custom Form Type as Global Service with Config Parameters
The better option seems to set some default parameters in the config file:
parameters:
gutensite_component.options.status:
0: Inactive
1: Active
gutensite_component.options.repetition:
0: Setup
1: Second
2: Minute
3: Hour
4: Day
5: Week
6: Month
7: Year
Then create a custom form type Gutensite\ComponentBundle\FormType\RepetitionType that loads the options from the config parameters. See the Documentation for a great example of this. Then just refer to that field type like this:
$builder->add('repetition', 'repetition', array(
'label' => 'Billing Cycle',
'help' => 'The repetition frequency when this service is billed.',
// default to monthly (the most common)
'empty_data' => 6,
'required' => TRUE
));
The inconvenient part of this solution, is that you have to either parameter to twig in your config (which is bloat for every template even if you don't need it), or always remember to manually pass the parameters to twig from your controller.
// I add to the standard object `$controller->view` which gets passed to Twig
$controller->view->options['repetition'] = $this->container->getParameter('gutensite_component.options.repetition');
To be accessed like:
<div class="priceValue label label-primary">${{ entity.price }}/<span class="billingCycle">{{ view.options.repetition[entity.repetition] }}</span></div>
This is more clunky than I would like but it is reusable. Maybe others have better solutions to pass the configuration to twig than what is represented here.
Other Suggestions?
Do you have any other suggestions, best practices or lessons learned? Please share.
What I would do is to save those values as objects of a new entity and set a manyToOne relation from your main entity (or any other entity as your calendar event entity) to the repetition entity
If so, you can easily add new repetitions every time you want or get all objects of the main entity using any specific repetition.
Also you can build a nice form for a new object of the main entity with an input (human readable) of repetition values:
$builder->add('repetition', 'entity', array(
'class' => 'AcmeDefaultBundle:Repetition', // This is your new 'repetition entity'
'property' => 'repetitionName', // The field of your 'repetition entity' that stores the name (the one that will show a human readable value instead of the id)
'expanded' => true, // True if you prefer checkbox instead of a dropdown list
'label' => 'Billing Cycle',
'help' => 'The repetition frequency when this service is billed.',
'required' => true,
));
Now when you want to show the name of the repetition in twig you will use:
<div class="billingCycle">{{ entity.Repetition.repetitionName }}</div> (you can also translate that value later)
A cleaner way (if you use it only for this entity) is to define a public method in your entity that returns you that array:
public function getRepetitionNames() {
return array(
0 => 'Setup',
1 => 'Second',
2 => 'Minute',
3 => 'Hour',
4 => 'Day',
5 => 'Week',
6 => 'Month',
7 => 'Year'
);
}
Another method to retrieve the label based by your "repetition" field value:
/**
* #param $key
* #return null
*/
function getRepetitionLabel(){
$repetitions = $this->getRepetitionNames();
return isset($repetitions[$this->repetition]) ? $repetitions[$this->repetition] : 0;
}
Will be much easier to access it in twig now:
<div class="billingCycle">{{ entity.repetitionLabel }}</div>
Last, in your form use your entity to retrieve the values:
$object = $builder->getData();
$repetitionChoices = $object->getRepetitionNames();
$builder->add('repetition', 'choice', array(
'label' => 'Billing Cycle',
'help' => 'The repetition frequency when this service is billed.',
'choices' => $repetitionChoices
'empty_data' => 6,
'required' => TRUE
));
If you plan to use it in more entities, you could use a interface.

show month number instead of month name on symfony2 formbuilder

It might be ridiculous quesion, but I can't find the way with googling.
I am making form like this.
$form = $this->createFormBuilder($searchTime)
->add('date','date',array(
"property_path" => false,
'years' => $years,
'data' => new \Datetime()
but it shows month select box as name such as jun,july,aug
however I want to show number here 6,7,8 ....
How can I make it ?
Maybe it's worth a try to specify a format, as the reference says:
$builder->add('date', 'date', array(
'widget' => 'choice',
'format' => 'yyyy-MM-dd',
// ...
));
The reference says, that if your widget is choice and you specify the format then the selects will be rendered in the order of the format. Maybe the select format is also will be adjusted to the format pattern.
(The month without leading zeros would be: yyyy-M-dd)

Drupal 7 db_insert on WYSIWYG textarea field

this is my first post here at stackoverflow and i'll try make sharp and short ;-)
I am running into problems when inserting a textarea form field using CKeditor into the database.
Here is my form element:
$form['add']['description'] = array(
'#wysiwyg' => true,
'#name' => 'description',
'#title' => t('description'),
'#type' => 'text_format',
'#base_type' => 'textarea',
);
When submitting the form i do get a SQL error like this because Drupal appends the placeholder elements 'value' and 'format'
db_insert failed. Message = SQLSTATE[21S01]:
Insert value list does not match column list:
1136 Column count doesn't match value count at row 1,
query= INSERT INTO {tablename} (description)
VALUES (:db_insert_placeholder_13_value, :db_insert_placeholder_13_format)
Unfortunately i exactly have to set up the textarea this way to make the CKeditor work. Can you advice me how to get rid of the
:db_insert_placeholder_13_value,
:db_insert_placeholder_13_format
to a single variable again?
I really appriciate your help
PROBLEM SOLVED --- silly me, should have used my glasses more :-D
Just use the correct array index inside the submit hook for saving the data to the database and it will work:
function MYMODULE_form_add_submit($form, &$form_state) {
...
'description' => $form_state['values']['description']['value'],
...
}
If you're just interested in the text itself (not the format), add a validation handler for the form and use something like this
function MYMODULE_form_name_validate($form, &$form_state) {
$form_state['values']['description'] = $form_state['values']['description']['value'];
}

Symfony 2, how to persist join table entities?

This is such a trivial problem that I can't believe I couldn't find an answer.
Symfony 2, doctrine 2.1. I've got two entities and one intermediate entity (join table). User, Pref, and UsersPrefs. Pref table is dictionary table, so that I could change pref name in one place only. Ok, let's see the picture:
infographic http://dl.dropbox.com/u/22495762/infographic.png
As You can see, I want to have a checkbox group, with all the possible choices (prefs) and preferred choices checked. So, if there are 3 prefs, and only 2 selected by the user, there should be 3 checkboxes, 2 selected.
It's simple, if done plain PHP - query database twice to get list of all prefs and user prefs, render checkboxes depending on values, add some actions to handle form submit, done.
But for the life of God I can't get this to work using symfony & doctrine. I was able to get to the point where I can update relationships in doctrine and further in database, but I'm using raw query values for that:
$data = $request->request->get('some_form');
and this supposedly isn't the way it should be done?
Morevoer, I'm completely stuck as to how should I display checkbox list. I either get list of all options, none checked, or only user options, all checked. Or 'left joined' result set with checkboxes for all cases, useless anyway.
I've come to the point where I tried to overload twig checkbox template, but I couldn't pass variables to the form template, and that was the last straw...
EDIT:
This way I'm getting group of checkboxes, not connected to user choices:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\Pref',
'expanded' => 'true',
'multiple' => 'true',
'property' => 'name'
))
And this way I'm getting only user choices, all checked:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\UserPrefs',
'multiple' => 'false',
'expanded' => 'false',
'property' => 'pref.name',
'query_builder' => function(EntityRepository $er) use ($id) {
return $er->createQueryBuilder('u')
->where("u.user = :id")
->setParameter('id', $id)
;
},
))
And I tried left joins and other options, but at best I could get list of all possible options for all possible users, checked accordingly.
EDIT (POSSIBLE SOLUTION):
I'm displaying checkbox group:
->add('pref_ids', 'choice', array(
'choices' => array(
'1' => 'pref one',
'2' => 'pref two',
'3' => 'pref three',
),
'expanded' => 'true',
'multiple' => 'true'
))
I've added $pref_ids array in User entity. Now I just need to set values in array according to preferences chosen by user:
public function setPrefIds()
{
$prefs = $this->getPrefs();
$this->pref_ids = array();
foreach($prefs as $pref){
array_push($this->pref_ids, $pref->getPref()->getId());
}
return $this;
}
This way I get appropriate checkboxes checked.
Writing values to database is reversal of the process. I'm getting input values from request:
$data = $request->request->get('edit_form');
var_dump($data['pref_ids']);
Removing all user prefs:
foreach ($userPrefs as $pref){
$em->remove($pref);
}
And setting actual associations in doctrine from ids:
$entity->setPrefsById($em, $data['pref_ids']);
Here I'm passing entity manager to entity itself, but I need to refactor it, because it looks kinda messy this way.
Then $em->flush(); and that's it.
That's the best I could come up with. Probably it's overcomplicated and should be done entirely different way. Unfortunately couldn't figure out this "other way".
You need the choice field type: http://symfony.com/doc/current/reference/forms/types/choice.html
In your builder, it will be something like
$builder->add('prefs', 'choice', array('multiple' => true, 'expanded' => true, 'choices' => fetch the available prefs from the database here);
Edit: Sorry I'm mistaken, you need the "Entity" type, which fetches automatically the choices from the database: http://symfony.com/doc/current/reference/forms/types/entity.html
You must still put multiple => true expanded => true to get checkboxes.

Resources