? ? Pending

User tests: Successful: Unsuccessful:

avatar Bakual
Bakual
18 Jan 2017

Pull Request for Issue #13606 .

Currently, when you have a calendar field the timezone with each save the timezone is added/substracted from the date, resulting in a shift of the date/time with each save. This is especially bad if you only want to store the date plus have a negative timezone (eg New York), then the date shifts one day back with each save.
Also when the date is displayed in frontend, it is off by the timezone as well.

Main issue is that the calendar formfield expects the value stored as UTC and applies the timezone when shown in the form. But currently, the value isn't converted to UTC during save which results in that shift.
Also the timezone isn't applied when the value is shown in frontend.

Summary of Changes

  • Using JHtml::date to show the date in frontend. This automatically applies the user timezone to the value.
  • Using JText::_() to show the date in a localised format. With this PR this format is hardcoded to DATE_FORMAT_LC4 which will only show the date. That likely needs to be improved but I'm not yet sure how. It's not directly in the scope of this PR and can be done later fine. Also overrides are possible to change that format easily.
  • The format parameter of the field is replaced with a showtime parameter. It will control if the time is displayed or not both in forms and when the item is shown in frontend. It takes translated format strings.
  • Introduces a new plugin event "onAfterDataValidation". Also adds a new "onBeforeDataValidation" event and deprecates the existing "onUserBeforeDataValidation". Here I need input from @wilsonge as he initially created this event with #10751. Imho the name of the event is misleading as it has nothing to do with com_users (it's a general event).
  • During that new event, the fields plugin will take the validated fields data, store it in a private property and use it in the onContentAfterSave event to store it into database. The "onContentBeforeSave" method isn't needed anymore in the fields plugin.
  • Expanded the current onContentBeforeSave and onContentAfterSave events so they not only pass the table object but also the validated data. The fields data can then be taken simply from that $data array. I'm sure other extensions will find that useful as well.

Testing Instructions

  • Make sure editing field values works as expected.
  • Make especially sure calendar formfields don't change the value on repeated saves and that the displayed value is same in frontend and backend. Especially also check with negative timezones.

Documentation Changes Required

The new adjusted event needs to be documented on https://docs.joomla.org/Plugin/Events.

avatar Bakual Bakual - open - 18 Jan 2017
avatar Bakual Bakual - change - 18 Jan 2017
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 18 Jan 2017
Category Libraries Front End Plugins
avatar wilsonge
wilsonge - comment - 18 Jan 2017

Good by me. Remember to update the onUserBeforeDataValidation event in com_users to note the deprecation - the idea was that event was a generic version of what @rdeutz did #10351 and I just forgot to change the name to be generic too

avatar Bakual Bakual - change - 18 Jan 2017
Labels Added: ?
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 19 Jan 2017

I have tested this item successfully on c02720d

Re-Saved Article in Front- and Backend with "Universal Time Zone", got same Date. Changing Time Zone to "Chicago" changed Date one Day back (from 2017-01-12 to 2017-01-11), re-saving in Front- and Backend dosn't change Date.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/13638.

avatar franz-wohlkoenig franz-wohlkoenig - test_item - 19 Jan 2017 - Tested successfully
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 19 Jan 2017

@Bakual wasn't able to get Time in Calendar-Plugin, default Value is %Y-%m-%d, there should also a Time Value possible.

avatar Bakual
Bakual - comment - 19 Jan 2017

wasn't able to get Time in Calendar-Plugin, default Value is %Y-%m-%d, there should also a Time Value possible.

Yep, that's the part with the formatting in frontend. I need a solution for that (probably a new parameter).

@laoneo also raised a concern that we store data in a plugin property. I'm not so sure if it's an issue as we do a similar thing in the debug plugin.
The other approach would be to expand the onContentAfterSave event with the validated data. So instead of doing "onContentAfterSave($context, $item, $isNew)" we would do "onContentAfterSave($context, $item, $isNew, $data = array())". That would then allow to fetch the validated data directly in that event ($item only contains data matched to the database table).

avatar joomdonation
joomdonation - comment - 20 Jan 2017

The other approach would be to expand the onContentAfterSave event with the validated data. So instead of doing "onContentAfterSave($context, $item, $isNew)" we would do "onContentAfterSave($context, $item, $isNew, $data = array())".

To me, that would be better solution compare to the current one. However, there are two things;

  1. If you pass validated data ($data variable) to the event trigger (this line https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/admin.php#L1192, correct ?) , for existing plugins which listen to that event, I guess there would be warning because it doesn't have $data variable in the method?

  2. Since $this->event_after_save could be a custom one (for example onSubscriptionPlanAfterSave, onEventAfterSave...), if third party extension want to use this custom fields feature, they would have to write a new plugin to just save custom fields data?

So if we have to introduce a new event like in this PR, maybe we could trigger new event after this line https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/admin.php#L1192

$dispatcher->trigger('onDataAfterSave', array($context, $table, $isNew, $data));

Or

$dispatcher->trigger('onItemAfterSave', array($context, $table, $isNew, $data));

How do you think about it?

avatar Bakual
Bakual - comment - 20 Jan 2017

If you pass validated data ($data variable) to the event trigger (this line https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/admin.php#L1192, correct ?) , for existing plugins which listen to that event, I guess there would be warning because it doesn't have $data variable in the method?

Yes, that line. And no, there is no warning. PHP doesn't generate a warning if you call a method with to many arguments.

Since $this->event_after_save could be a custom one (for example onSubscriptionPlanAfterSave, onEventAfterSave...), if third party extension want to use this custom fields feature, they would have to write a new plugin to just save custom fields data?

3rd parties need to trigger the onContent.... events anyway. Otherwise the fields plugin will not work. The plugin is already listening on several such events (including the onContentAfterSave one). So there will be no difference here. Only thing would be if the extension triggers the event in its own code, it will need to add $data to it as well. But they need to adapt their code to support fields anyway.

The only way this can be an issue imho is when a 3rd party extension already passed additional arguments to that event. I don't know how probable that is but imho it's the risk of the 3rd party if he does that.

I wouldn't add a new event right after the existing one. Either we add one in a place where there is currently none, or we adjust the existing one.

avatar joomdonation
joomdonation - comment - 21 Jan 2017

Yes, that line. And no, there is no warning. PHP doesn't generate a warning if you call a method with to many arguments.

Thanks, I didn't know that. I thought the number arguments must be equal.

I wouldn't add a new event right after the existing one. Either we add one in a place where there is currently none, or we adjust the existing one.

The reason I suggested to add a new event is because I thought that add new parameter to event trigger will causes backward compatible issues with existing plugins. Now I know that It is OK to add new parameters to existing event trigger, I will be happy if you add $data to event_after_save at this line https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/admin.php#L1192

Maybe add $data to event_before_save trigger at this line as well https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/model/admin.php#L1171

avatar Bakual
Bakual - comment - 21 Jan 2017

Thanks, I didn't know that. I thought the number arguments must be equal.

I wasn't sure myself, had to try it and verify with StackOverflow ?

Maybe add $data to event_before_save trigger at this line as well

Yeah, that was my thinking as well. Both events should have similar signatures.
I'll update this PR when I get some time (hopefully this night)

avatar joomdonation
joomdonation - comment - 21 Jan 2017

Great. I will test it when it is ready :)

avatar Bakual Bakual - change - 22 Jan 2017
The description was changed
avatar Bakual Bakual - edited - 22 Jan 2017
avatar Bakual
Bakual - comment - 22 Jan 2017

@joomdonation Removed the new events (will probably do a separate PR for those) and adjusted the existing save events to pass also the validated data.

avatar laoneo
laoneo - comment - 23 Jan 2017

I very like the approach. If there is a way to handle the formats consistently then the issue is solved properly.

avatar Bakual
Bakual - comment - 23 Jan 2017

If there is a way to handle the formats consistently then the issue is solved properly.

Not in 3.x for sure. Maybe in 4.0 if we get a way that the JavaScript code understands PHP date formats and we can break B/C with all existing forms. ?
The new translateFormat attribute may help with a transition since developers no longer need to explicitely specify the format in most cases.

avatar laoneo
laoneo - comment - 23 Jan 2017

But then I would suggest that we offer in the custom field only the formats which are available for the front for the datepicker and and not a free text field.

avatar Bakual
Bakual - comment - 23 Jan 2017

But then I would suggest that we offer in the custom field only the formats which are available for the front for the datepicker and and not a free text field.

Yes, that needs improvement anyway.
I think we could also use an approach where we make use of the new attributes of that field: "translateFormat" and "showTime". If we add a setting "Show Time" we could get rid of any format setting. The formfield would use those two strings:

DATE_FORMAT_CALENDAR_DATE="%Y-%m-%d"
DATE_FORMAT_CALENDAR_DATETIME="%Y-%m-%d %H:%M:%S"

And for the display part we can toggle between

DATE_FORMAT_LC4="Y-m-d"
DATE_FORMAT_LC5="Y-m-d H:i"

I think that would actually solve most use cases without becoming overly complex.

avatar laoneo
laoneo - comment - 23 Jan 2017

Absolutely, one with time and one without.

avatar joomla-cms-bot joomla-cms-bot - change - 23 Jan 2017
Category Libraries Front End Plugins Administration Language & Strings Libraries Front End Plugins
avatar Bakual Bakual - change - 23 Jan 2017
Labels Added: ?
avatar Bakual
Bakual - comment - 23 Jan 2017

@laoneo I have now replaced the format parameter with a showtime parameter.
By default it will only show the date and the calendar popup doesn't have a time selector.
If enabled, the time selector will appear and the time will be shown both in forms and items.

What do you think?

avatar Bakual Bakual - edited - 23 Jan 2017
avatar Bakual Bakual - change - 23 Jan 2017
The description was changed
avatar Bakual Bakual - edited - 23 Jan 2017
avatar laoneo
laoneo - comment - 23 Jan 2017

Why not just making a drop down with available the formats, for me there is no need to have a text field here as we are not supporting it anyway for the front end display.

avatar laoneo
laoneo - comment - 27 Jan 2017

Can you please fix the conflicts, would love to see it in the first beta ?

avatar laoneo
laoneo - comment - 30 Jan 2017

I have tested this item successfully on f3682a0


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/13638.

avatar laoneo laoneo - test_item - 30 Jan 2017 - Tested successfully
avatar laoneo
laoneo - comment - 30 Jan 2017

@franz-wohlkoenig can you please test it again, as there have been many changes since your latest test. Thanks!

avatar franz-wohlkoenig
franz-wohlkoenig - comment - 30 Jan 2017

I have tested this item successfully on f3682a0


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/13638.

avatar franz-wohlkoenig franz-wohlkoenig - test_item - 30 Jan 2017 - Tested successfully
avatar wilsonge wilsonge - close - 30 Jan 2017
avatar wilsonge wilsonge - merge - 30 Jan 2017
avatar wilsonge wilsonge - change - 30 Jan 2017
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2017-01-30 09:53:59
Closed_By wilsonge
avatar wilsonge
wilsonge - comment - 30 Jan 2017

Well done everyone!

Add a Comment

Login with GitHub to post a comment