Problem/Motivation

The core ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime.module because they define their `default_widget` as "datetime_default", which is provided by the datetime.module:

/**
 * Defines the 'timestamp' entity field type.
 *
 * @FieldType(
 *   id = "timestamp",
 *   label = @Translation("Timestamp"),
 *   description = @Translation("An entity field containing a UNIX timestamp value."),
 *   default_widget = "datetime_default", // <-- provided by datetime.module
 *   default_formatter = "timestamp",
 *   constraints = {
 *     "ComplexData" = {
 *       "value" = {
 *         "Range" = {
 *           "min" = "-2147483648",
 *           "max" = "2147483648",
 *         }
 *       }
 *     }
 *   }
 * )
 * )
 */

Proposed resolution

Update the annotation on these classes to use "datetime_timestamp" as the default widget.

Add a functional test to make sure the widget works.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mpdonadio created an issue. See original summary.

Berdir’s picture

(00:34:57) berdir: mpdonadio: I doubt that makes sense anyway since that doesn't work on unix timestamp fields? should just be dropped?
(00:35:27) berdir: 2552799
(00:35:34) Druplicon: https://drupal.org/node/2552799 => FieldType with no available widget causes Fatal error #2552799: FieldType with no available widget causes Fatal error => 64 comments, 1 IRC mention
(00:35:39) berdir: mpdonadio: ^ that issue added that
(00:35:47) berdir: but it has no_ui, so not sure why that was added
Berdir’s picture

Component: base system » field system
Issue tags: +Novice

I was wrong, we do have one. \Drupal\Core\Datetime\Plugin\Field\FieldWidget\TimestampDatetimeWidget/datetime_timestamp is what they should use.

That makes this a novice issue I think, just switch to the right type. Since they are not UI addable, I'm not sure we can write any useful tests, though.

Berdir’s picture

mpdonadio’s picture

mpdonadio’s picture

Status: Active » Needs work
Issue tags: -Novice +Needs tests
FileSize
2 KB

Not sure this is really a novice issue.

#2552799: FieldType with no available widget causes Fatal error added the widget to this field.

#2707057: Remove no_ui from timestamp field type made Timestamp available from the UI.

With the attached, adding this field to an entity and then trying to add the entity via the UI fatals when just loading the page:

Exception: The timestamp must be numeric. in Drupal\Component\Datetime\DateTimePlus::createFromTimestamp() (line 172 of core/lib/Drupal/Component/Datetime/DateTimePlus.php).
Drupal\Core\Datetime\Plugin\Field\FieldWidget\TimestampDatetimeWidget->formElement(Object, 0, Array, Array, Object) (Line: 324)
Drupal\Core\Field\WidgetBase->formSingleElement(Object, 0, Array, Array, Object) (Line: 189)
Drupal\Core\Field\WidgetBase->formMultipleElements(Object, Array, Object) (Line: 104)
Drupal\Core\Field\WidgetBase->form(Object, Array, Object) (Line: 168)
Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm(Object, Array, Object) (Line: 54)
Drupal\Core\Entity\ContentEntityForm->form(Array, Object) (Line: 118)
Drupal\node\NodeForm->form(Array, Object) (Line: 115)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object)
...

The timestamps on nodes, etc, use this widget for base fields. I suspect those are never empty, so they never barf here. I think I see what is happening, but want to wrap my head around this first before posting more work.

I'll see if I can work this into a failing test tonight or tomorrow.

mpdonadio’s picture

Status: Needs work » Needs review
FileSize
5.87 KB
3.87 KB

Widget fix and my work-in-progress on the test.

Status: Needs review » Needs work

The last submitted patch, 7: 2802663-07.patch, failed testing.

amateescu’s picture

With the attached, adding this field to an entity and then trying to add the entity via the UI fatals when just loading the page:

Which field type are you adding? With the patch from #6 applied, I added a Timestamp field to a node bundle, it used the 'datetime_timestamp' widget by default and I see no error when adding a node of that type :/

mpdonadio’s picture

#9, it was a timestamp w/o a default value.

-    $default_value = isset($items[$delta]->value) ? DrupalDateTime::createFromTimestamp($items[$delta]->value) : '';
+    $default_value = isset($items[$delta]->value) && is_numeric($items[$delta]->value) ? DrupalDateTime::createFromTimestamp($items[$delta]->value) : '';

IIRC correctly from debugging this the other night, $items[$delta]->value was coming in as an empty string, which DrupalDateTime::createFromTimestamp() didn't like b/c DateTimePlus::createFromTimestamp() has an explicit is_numeric() check, which led to adding this hunk.

amateescu’s picture

Weird, the timestamp field that I created also didn't have a default value..

mpdonadio’s picture

I'll check this again tonight; I was working on a few issues, but I am nearly sure I was doing a clean install between all of them. My dev machine MAMP is also set for PHP7 (so tests run faster...), so I will double check with 5.5 and 5.6, too. It probably doesn't make a difference, but my clean install script defaults to adding a dev-oriented settings.local.php. I may also switch the test to WTB so I can finish it quicker, and then change it to BTB once we know it is good (I'm finding BTB much harder to write from scratch b/c debugging output is less convenient).

mpdonadio’s picture

I can't make #6 happen any more. No clue why I saw that error other than maybe my database had cruft in it from another issue and I wasn't actually developing from a clean install.

Here is basic coverage of the widget. Probably can be refined. Tried to simplify some of the patterns existing tests use, but may have gone a little too far with assumptions / hardcoded values.

jhedstrom’s picture

This is looking good--tagging for an IS update to address the proposed resolution from 'no clue' :)

Some tiny nits:

  1. +++ b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php
    @@ -0,0 +1,147 @@
    + * @group somegroup
    

    Needs a real group? :)

  2. +++ b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php
    @@ -0,0 +1,147 @@
    +   * An array of display options to pass to entity_get_display()
    

    Missing period.

  3. +++ b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php
    @@ -0,0 +1,147 @@
    +  public static $modules = ['node', 'entity_test', 'field_ui'];
    ...
    +    $edit = array(
    

    Class is using a mix of traditional array syntax and bracket, should probably be all brackets.

mpdonadio’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Nits will be picked shortly.

mpdonadio’s picture

Addressed #14. The "field" @group seems most appropriate; this really isn't datetime proper. Also added an assertion to make sure the "datetime_timestamp" widget is actually used.

jhedstrom’s picture

+++ b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php
@@ -0,0 +1,151 @@
+

Extra line break here, I missed this before.

I think this is RTBC once that is fixed.

mpdonadio’s picture

FileSize
7.03 KB
786 bytes

Addressed #17 and two other minor things phpcs noticed.

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

I think this is good to go!

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

I'm pondering if there are API or BC implications of changing this. Existing fields won't be affected right?

But should the datetime module alter the defaults to use it's formatter when it is installed?

mpdonadio’s picture

#20, I don't think there are any API implications here, which is why I added a pretty explicit test. I don't think there are any BC problems either. Bottom line is that the timestamp and datetime widgets are formatters aren't compatible because the typed data is different. Timestamps are ints, and datetime are DrupalDateTime (fancy \DateTime). If the datetime widgets or formatters get used with a timestampitem, then you get a fatal (maybe a nasty warning, would have to force a way to reproduce this again). I think we also have pretty decent coverage on created and changed on nodes, which use the timestamp stuff.

Down the road, we could consider whether we want the datetime widgets/formatters could extend the timestamp ones, but haven't put much thought into whether it is worthwhile.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

charginghawk’s picture

Status: Needs review » Reviewed & tested by the community

I've tested this and it works for me. Please merge! Right now, timestamp fields just aren't working on default installs.

(Arrived here via #2836053: Datetime timestamp field)

jibran’s picture

+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php
@@ -13,7 +13,7 @@
- *   default_widget = "datetime_default",
+ *   default_widget = "datetime_timestamp",

+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php
@@ -10,7 +10,7 @@
- *   default_widget = "datetime_default",
+ *   default_widget = "datetime_timestamp",

+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
@@ -13,7 +13,7 @@
- *   default_widget = "datetime_default",
+ *   default_widget = "datetime_timestamp",

Don't we need an upgrade path for existing fields?

But should the datetime module alter the defaults to use it's formatter when it is installed?

I think this much safer approach also datetime_install can update existing fields widgets.

jibran’s picture

Title: The core ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime.module » ChangedItem, CreatedItem, and TimestampItem fields should have an implicit dependency on datetime module
Status: Reviewed & tested by the community » Needs work

NW for #24.

Berdir’s picture

Those are plugin definitions, the only update it would need is a cache clear.

mpdonadio’s picture

Title: ChangedItem, CreatedItem, and TimestampItem fields should have an implicit dependency on datetime module » ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module

But should the datetime module alter the defaults to use it's formatter when it is installed?

#24, I don't see how datetime.module can do this. The typed data is different. Timestamps, as provided by core, are signed integers. Datetime (and daterange) are ISO strings. We could probably support this, but it is decent change to the widgets/formatters and we are trying to simplify the internals of them right now. There are also field setting differences. We would also have to have an uninstall hook to switch them back if datetime.module gets uninstalled. Also not 100% sure we can warn people about this before uninstall with the way dependencies work.

?

What is the current consensus on empty update hooks / post update hooks? I can add one, but a decent amount are being stripped on commit because we have rebuild already from other ones.

jibran’s picture

Empty post-update hooks should be fine.

mpdonadio’s picture

Status: Needs work » Needs review
FileSize
7.7 KB
688 bytes

OK, here's an empty post-update hook to force plugin definitions to be re-read.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Over to @alexpott then.

xjm’s picture

Priority: Normal » Major

Over to @alexpott then.

Drupal 8 currently has seven active committers; let's not make assumptions.

I would not normally backport this to a patch release, but since having correct dependencies has implications for dependency management, data integrity, etc., I'm considering whether to add it to 8.3.x. It also sounds like it is major if this is causing the feature to not work at all on default installations.

Meanwhile, committed to 8.4.x. Leaving RTBC against 8.3.x while I get a second opinion on the backport.

xjm’s picture

Version: 8.3.x-dev » 8.4.x-dev
Status: Reviewed & tested by the community » Needs review

Actually, sorry. I just noticed this is adding a dependency in core/lib on datetime.module, no? We're not supposed to do that. Reverted and setting back to NR to discuss that.

xjm’s picture

Title: ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module » ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module, causing exceptions to be thrown during validation
Berdir’s picture

Title: ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module, causing exceptions to be thrown during validation » ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module
Status: Needs review » Reviewed & tested by the community

Nope, the opposite, this removes that dependency.

datetime_timestamp, despite the misleading name is \Drupal\Core\Datetime\Plugin\Field\FieldWidget\TimestampDatetimeWidget. datetime_default is \Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter.

xjm’s picture

Title: ChangedItem, CreatedItem, and TimestampItem fields have an implicit dependency on datetime module » Exceptions due ChangedItem, CreatedItem, and TimestampItem implicit dependencies on datetime module
Version: 8.4.x-dev » 8.3.x-dev
Status: Reviewed & tested by the community » Fixed

Oh, hah. Thanks @Berdir. Okay, recommitting to 8.4.x based on that and also backporting to 8.3.x, because yeah, that's definitely a problem. Thanks!

xjm’s picture

jibran’s picture

Drupal 8 currently has seven active committers; let's not make assumptions.

I was not making assumptions. I just wanted to be sure that his concerns in #20 are addressed properly. If you were fine with answering those then I have no problem with it. :)

Thank you for committing this and thank you for all the awesome work with RTBC queue.

charginghawk’s picture

Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.