I'm reaching out because I just can't find out why my custom datetime field isn't saving its value after I submit.
Context:
I've created a field containing two datetime fields. I will use it to add or remove events from an event list, depending on whether they have passed or not (for example if a festival is scheduled from the 12 to the 14 of December, the event will be removed after the 14th).
Events in my case are generated from a custom entity, I can manage its fields from my back office. My goal is to get the the dates from my custom datetime field on twig to filter which events are showed.
I know I can just add two Date fields but I find it lacks the elegance I seek.
My code:
So I have created a custom field that itself contains two datetime fields. I followed many tutorials to find a version that works for me and here is the code for my Field Type, Widget and Formatter
- Field Type: ScheduleItem.php
class ScheduleItem extends FieldItemBase {
/**
* {@inheritdoc}
*/
public function isEmpty() {
$isEmpty =
empty($this->get('start')->getValue()) &&
empty($this->get('finish')->getValue());
return $isEmpty;
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties = [];
$properties['start'] = DataDefinition::create('datetime_iso8601')
->setLabel(t('Date de publication'));
$properties['finish'] = DataDefinition::create('datetime_iso8601')
->setLabel(t('Date de suppression'));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
$columns = [
'start' => [
'type' => 'varchar',
'mysql_type' => 'datetime',
'not null' => FALSE,
'default' => NULL,
],
'finish' => [
'type' => 'varchar',
'mysql_type' => 'datetime',
'not null' => FALSE,
'default' => NULL,
],
];
return [
'value' => $columns,
// @DCG Add indexes here if necessary.
];
}
Not much to say here. I don't know if there is a conflict in the types that I use, as mysql_type
, type
and DataDefinition::create
have different values...
- Field Widget: ScheduleWidget
class ScheduleWidget extends DateTimeWidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(
FieldItemListInterface $items,
$delta,
Array $element,
Array &$form,
FormStateInterface $formState
) {
$element += array(
'#delta' => $delta,
);
$element['start'] = [
'#type' => 'datetime',
'#title' => $this->t('Date de publication'),
// Set here the current value for this field, or a default value (or
// null) if there is no a value
'#default_value' => isset($items[$delta]->start) ?
$items[$delta]->start : null,
'#empty_value' => '',
];
$element['finish'] = [
'#type' => 'datetime',
'#title' => $this->t('Date de suppression'),
'#default_value' => isset($items[$delta]->finish) ?
$items[$delta]->finish : null,
'#empty_value' => '',
];
return $element;
}
}
Contrary to most custom field widgets I extend DateTimeWidgetBase
and not WidgetBase
, the point here is to use the pre-made massageFormValues
function from the class. It is supposed to convert my values to a database-ready format if I understood correctly, but so far it hasn't helped me.
- Field Formatter: ScheduleDefaultFormatter.php
class ScheduleDefaultFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode)
{
$elements = [];
foreach ($items as $delta => $item) {
$elements[$delta] = [
'#start' => $item->start,
'#finish' => $item->finish
];
}
return $elements;
}
}
Thats pretty much it for my code, I thought it was good, well it looked as such to me but...
THE ISSUE
When I added my new custom field to my event entity in the "Manage Fields" section, created a new event and added dates to it, I got...
This value should be of the correct primitive type.
What I tried
I dumped $values
just before massageFormValues
returned it and this is what it looks like:
My question to you, why isn't it working ?
I tried being as clear as possible, however my experience on Drupal is still limited, don't hesitate if you need more information about my code, as long as it helps solving the issue!