8000 [HttpFoundation] adds getDate method to the ParameterBag class by maldoinc · Pull Request #19296 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[HttpFoundation] adds getDate method to the ParameterBag class #19296

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

Closed
wants to merge 6 commits into from
Closed

[HttpFoundation] adds getDate method to the ParameterBag class #19296

wants to merge 6 commits into from

Conversation

maldoinc
Copy link
Contributor
@maldoinc maldoinc commented Jul 5, 2016
Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR #6718

This adds a getDate method to the ParameterBag class which convert the specified key to a DateTime object

Edit: The main motivation behind this PR (from my PoV at least) is to avoid repetitive tasks with handling date parameters on GET requests.


This is a continuation of #19295. Moved here in order to have a cleaner git history.

@unkind
Copy link
Contributor
unkind commented Jul 5, 2016

You can rebase your commit history and git push -f instead of creating new PR.

public function getDate($key, $format = 'Y-m-d', $default = null, $timeZone = null)
{
if (!$this->has($key)) {
return $default;
Copy link
Member

Choose a reason for hiding this comment

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

This gives no guaranties whatsoever about the type of the return value ($default can be anything).
Should default be a plain string that is turned to a date instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could very well be, I like this more than manually constructing a DateTime object for the default parameter.

So you can call it as follows: $bag->getDate('from', 'Y-m-d', '2016-01-01')

Yeah, perhaps we can go this way.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not typehint $default + $timezone? Fixes violating the return type :)

@nicolas-grekas nicolas-grekas changed the title added getDate/getDateTime methods to the parameterbag class [HttpFoundation] added getDate/getDateTime methods to the ParameterBag class Jul 6, 2016
@maldoinc maldoinc changed the title [HttpFoundation] added getDate/getDateTime methods to the ParameterBag class [HttpFoundation] adds getDate method to the ParameterBag class Jul 6, 2016
*/
public function getDate($key, $format, $default = null, $timeZone = null)
{
$time = $this->get($key, (string) $default);
Copy link
Contributor

Choose a reason for hiding this comment

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

What about

if (null === ($time = $this->get($key, $default))) {
    return null;
}

Next, if $format is invalid (ie false === $result) i would expect a \LogicException or something.

Copy link
Contributor Author
@maldoinc maldoinc Jul 6, 2016

Choose a reason for hiding this comment

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

Not too sold on creating a variable and checking for value in the same line, however that is a matter of preference.

Early return might be doable, but I avoided it because fabbot doesn't accept return null; but wants just a return; which technically both return null but I still see it as a void vs null issue.

Regarding \LogicException: None of the methods of this class throws an exception for invalid input. (e.g.: getInt rather than checking if it's a valid number or not it simply type-casts it).

Copy link
Contributor
@ro0NL ro0NL Jul 6, 2016

Choose a reason for hiding this comment

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

Do it in 2 lines then :) Its more about not casting $default, and rely on whatever value $time is. (null, valid or invalid).

Hence i would throw an exception when the value is invalid for the given format. Ignoring the user's expected format and just return null can be a real WTF. This is also the difference compared to getInt, etc. However it can also be explained as the user responsibility to validate (still we cannot differentiate between invalid or default/null) , but imo it would be the added value for this shortcut ;-)

Separating null from void is a good thing :) And this should be accepted by now afaik (symfony/symfony-docs#6614)

Copy link
Member

Choose a reason for hiding this comment

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

I agree about not casting $default

@xabbuh
Copy link
Member
xabbuh commented Aug 4, 2016

👍

Status: Reviewed

@nicolas-grekas
Copy link
Member

👍

@@ -133,7 +161,7 @@ public function testFilter()
'dec' => '256',
'hex' => '0x100',
'array' => array('bang'),
));
));
Copy link
Contributor

Choose a reason for hiding this comment

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

This cs fix should be done in 2.7, not in master, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The cs change was pushed accidentaly. Probably should be reverted.

@ro0NL
Copy link
Contributor
ro0NL commented Aug 7, 2016

Currently the default date is ignored whenever the user date is given but cannot be parsed (ie garbage). Im not sure thats convenient...

However i can imagine this heavily depends on what the end user wants/needs. Which probably also counts for exception handling on invalid date (vs returning null). Maybe this behaviour should be toggable after all via arguments =/

  • $throwOnInvalid: if true throw runtime exception whenever user date cannot be parsed, otherwise see $fallbackOnInvalid [default: false?]
  • $fallbackOnInvalid: if true fallback to default date whenever user date cannot be parsed, otherwise return null hardcoded (eg if the default date cannot be parsed, but this could also throw a logic exception then) [default: true?]

{
$time = $this->get($key, $default);

if ((null === $time) || $time instanceof \DateTimeInterface) {
Copy link
Member

Choose a reason for hiding this comment

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

(null === $time) parentheses unnecessary ?

@nicolas-grekas
Copy link
Member

So, given the amount of time/discussion we spent here, given that error handling is a domain matter, I'm not sure we want to add this anymore. The boilerplate it saves looks just better that creating a method with too many arguments and complexity inside.

@maldoinc
Copy link
Contributor Author

I'd say if this was to be merged it should be merged as it currently is.

I'm not okay with defining behaviour via arguments. If symfony prefers to throw exceptions then this should also throw otherwise if symfony prefers to return null then so be it.

@theofidry
Copy link
Contributor
theofidry 579F commented Aug 24, 2016

@maldoinc what's the benefit of adding that to the parameter bag? It's something that the serializer for example can already do:

$dateTime = $serializer->denormalize($parameters->get($key), \DateTime::class);

Sure it is slightly less convenient, but that's something serializer has been designed for whereas I hardly see why a ParameterBag should try to transform a value into an object.

@ro0NL
Copy link
Contributor
ro0NL commented Aug 25, 2016

Consider

public function getDate($key, $format, $default = null, \DateTimeZone $timeZone = null)
{
    if (null !== $default && !$default instanceof \DateTimeInterface) {
        $default = null === $timeZone ? \DateTime::createFromFormat($format, $default) : \DateTime::createFromFormat($format, $default, $timeZone);
        if (false === $default) {
            throw new \InvalidArgumentException('Invalid default date given');
        }
    }

    $time = $this->get($key, $default);
    if (null === $time || $time instanceof \DateTimeInterface) {
        return $time;
    }

    $result = null === $timeZone ? \DateTime::createFromFormat($format, $time) : \DateTime::createFromFormat($format, $time, $timeZone);

    return false === $result ? $default : $result;
}

I'd vote for that.

// this is in order to ensure compatibility with all php versions since
// some accept null as a TimeZone parameter and others do not
if (null !== $timeZone) {
$result = \DateTime::createFromFormat($format, $time, $timeZone);
Copy link
Member

Choose a reason for hiding this comment

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

If format is U, the timezone won't be applied.

@fabpot
Copy link
Member
fabpot commented Sep 14, 2016

I think I agree with @nicolas-grekas and @theofidry, and I think we should not add this to the core.

@HeahDude
Copy link
Contributor

Ok, let's close here then per @nicolas-grekas' comment.

@fabpot fabpot closed this Sep 17, 2016
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.

10 participants
0