Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow extended ISO datetime format to be marshalled. #10587

Merged
merged 7 commits into from Jul 10, 2017

Conversation

dereuromark
Copy link
Member

Implements #10586

A first stab at the issue.
I would only recommend adding the single one ISO format 'Y-m-d\TH:i:s.uO' which CakePHP generates on output in JSON files, so when doing the reverse, import, it can safely and directly convert back into the DB format.

Any better idea on the subject?

@dereuromark dereuromark added this to the 3.4.6 milestone Apr 26, 2017
@@ -114,7 +117,8 @@ public function toDatabase($value, Driver $driver)
$value = new $class('@' . $value);
}

return $value->format($this->_format);
$format = (array)$this->_format;
return $value->format(array_shift($format));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing blank line before return statement

@@ -206,6 +210,22 @@ public function marshal($value)
}

/**
* @param \Cake\I18n\Time|\DateTime $date
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing parameter comment

@dereuromark dereuromark changed the title Master iso datetime Allow extended ISO datetime format to be marshalled. Apr 26, 2017
protected $_format = 'Y-m-d H:i:s';
protected $_format = [
'Y-m-d H:i:s',
'Y-m-d\TH:i:s.uO',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will change the accepted data of every application using CakePHP. Not sure that is something we should be doing in a bugfix release.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be fully BC as it only adds on top. But sure, we can also either make it opt-in from app level, or do it in a minor.
Maybe there are also even better options here than this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is more that this adds a new valid input form that was not previously accepted. Developers may be surprised when previously invalid data becomes valid. Also concerning is that the new format includes timezone information which will require apps to ensure they are doing timezone conversions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually i ran into this issue because we started testing with MySQL 5.7, and the same app/db on MySQL 5.6 this "just works" (posting json from a js frontend to a controller)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that was my Pain Point too.
5.6 works fine, 5.7 crashes :/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying that 5.7 fails to insert rows with​ the current datetime format marshalling?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MySQL 5.6:

mysql> insert into `products` set `created` = '2017-05-02T08:30:44+00:00';
Query OK, 1 row affected, 1 warning (0.00 sec)

MySQL 5.7:

mysql> insert into `products` set `created` = '2017-05-02T08:30:44+00:00';
ERROR 1292 (22007): Incorrect datetime value: '2017-05-02T08:30:44+00:00' for column 'created' at row 1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. So having the ISO formats marshalled into datetime objects would likely help with that.

@@ -165,7 +169,7 @@ public function marshal($value)
$date = new $class($value);
$compare = true;
}
if ($compare && $date && $date->format($this->_format) !== $value) {
if ($compare && $date && !$this->_compare($date, $value)) {
Copy link
Contributor

@chinpei215 chinpei215 May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to check whether the date string can be restored here? I think this kind of check should be done by validation. If we could remove this check, people could use <input type="datetime-local"> field, that uses another date string formats, such as Y-m-d\TH:i or Y-m-d\TH:i:s.
Also, I think we have to change Validation::datetime() too. At the moment, it doesn't support for ISO datetime strings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an alternative PR for your recommendation? I am open to any other approach that would fix the issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we could get a consensus, I'll do that. Now I have a tricky way to pass the validation in my 2.x project:

public function isDateTime($check) {
    $value = array_values($check)[0];
    $value = implode(' ', explode('T', $value, 2));
    return Validation::datetime($value);
}

But it would be nice if Cake supports modern HTML features without this kind of trick.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check was originally intended to ensure that an ambiguous input format wasn't used resulting in a different datetime value than was in the request data. Perhaps that isn't useful, an we should instead rely on validation and app logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Then I'll send an alternative PR to 3.next when I have time. If it becomes to accept new date formats, the master branch would not be suitable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chinpei215 I consider this more a bugfix, because so far this kind of ISO date was wrongly not supported.
Are there any reasonable downsides of those "valid" date strings to be not turned down? Just saying "because so far wasnt allowed" is not a valid reason. Those already get exported like this for years, they must also be able get imported the same way.
I do not think this puts existing apps in jeopardy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dereuromark Changing string variable to array is not backward compatible. If someone uses a sub-class using _format property directly, the application would break. So this change must be done in 3.next.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair Point.

@darxmac
Copy link
Contributor

darxmac commented May 18, 2017

what are the chances this could get looked at again ? anything i can do ?

@dereuromark
Copy link
Member Author

@darxmac Do you have an idea of implementation that would work better than this one? It seems the compare part here causes some issues. The tests do not pass.

@darxmac
Copy link
Contributor

darxmac commented May 18, 2017

Looks like the format string was off a bit:

master-iso-datetime...darxmac:master-iso-datetime

update allowed date format string to match `ATOM` format
@codecov-io
Copy link

codecov-io commented May 18, 2017

Codecov Report

Merging #10587 into 3.next will decrease coverage by 0.04%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff              @@
##             3.next   #10587      +/-   ##
============================================
- Coverage     94.96%   94.91%   -0.05%     
+ Complexity    12326    12116     -210     
============================================
  Files           427      422       -5     
  Lines         30714    30100     -614     
============================================
- Hits          29168    28570     -598     
+ Misses         1546     1530      -16
Impacted Files Coverage Δ Complexity Δ
src/Database/Type/DateType.php 100% <ø> (ø) 7 <0> (ø) ⬇️
src/Routing/RouteCollection.php 100% <ø> (ø) 25 <0> (ø) ⬇️
src/Database/Type/TimeType.php 100% <ø> (ø) 1 <0> (ø) ⬇️
src/Database/Type/DateTimeType.php 96.73% <100%> (+0.22%) 50 <3> (+3) ⬆️
src/ORM/Association/HasMany.php 96.59% <0%> (-3.41%) 54% <0%> (-4%)
src/Event/EventManager.php 94.67% <0%> (-1.88%) 77% <0%> (ø)
src/Utility/Security.php 75.51% <0%> (-0.97%) 37% <0%> (-2%)
src/Database/Schema/SqlserverSchema.php 95.4% <0%> (-0.58%) 85% <0%> (ø)
src/Database/Schema/PostgresSchema.php 97.91% <0%> (-0.42%) 111% <0%> (ø)
src/ORM/Query.php 97.31% <0%> (-0.41%) 94% <0%> (-1%)
... and 75 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ad24a97...f7bc885. Read the comment docs.

@dereuromark
Copy link
Member Author

Looks like the tests are now green.

@markstory markstory modified the milestones: 3.4.7, 3.4.8 May 20, 2017
@markstory markstory changed the base branch from master to 3.next May 20, 2017 13:03
@markstory
Copy link
Member

Moved to 3.next as this is a bigger change than I think we should be putting into a bug fix release.

@dereuromark dereuromark modified the milestones: 3.5.0, 3.4.8 May 22, 2017
@dereuromark
Copy link
Member Author

@lorenzo What do you think?

@dereuromark
Copy link
Member Author

bump

@darxmac
Copy link
Contributor

darxmac commented Jun 15, 2017

anything else i could do to help move this along ?

*/
protected function _compare($date, $value)
{
foreach ((array)$this->_format as $format) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the other subclasses need any changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I could see.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok.

@markstory
Copy link
Member

@darxmac The earliest this will ship is 3.5.0 which hasn't even started beta/rc releases, so it will be a while even if this is merged today.

protected $_format = 'Y-m-d H:i:s';
protected $_format = [
'Y-m-d H:i:s',
'Y-m-d\TH:i:sP',
Copy link
Contributor

@inoas inoas Jun 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add Y-m-d\TH:i:s.u to that list?

That would allow support for datetime(6) see: #10439

Edit: And then also for class TimeType ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. You want to make a PR against this branch?
Not sure when I will be able to follow up here.

@dereuromark
Copy link
Member Author

We could also already merge this and further enhance with future on top PRs?

@markstory markstory self-assigned this Jul 3, 2017
@markstory markstory merged commit 29e1325 into 3.next Jul 10, 2017
@markstory markstory deleted the master-iso-datetime branch July 10, 2017 01:32
markstory added a commit to cakephp/docs that referenced this pull request Jul 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants