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

vCard 4.0: fix Name Property #146

Open
wants to merge 13 commits into
base: 2.0.0-dev
Choose a base branch
from

Conversation

helveticadomes
Copy link

fix Name Property (wrong order: FN and N have different orders!)
mandatory check for fullname (fix #113 ) based on #128

@helveticadomes
Copy link
Author

helveticadomes commented Mar 4, 2019

@Danger89 maybe you can help me

  • to pass travis checks
  • review the mandatory check
  • review the mandatory exception
  • confim that FN / N need that fix

@melroy89
Copy link

melroy89 commented Mar 4, 2019

Ah the name parser was also wrong. So the order was indeed wrong regarding lastname, firstname and additional.

It's also a best practice to add some additional unit testers with introducing new code.
Indeed the RFC 6350 says regarding FN: "The property MUST be present in the vCard object."

While the N (Name) SHOULD be present.

Is is OK to assume that when N is filled-in, FN can be derived from that? So still ending up in the vCard, without explicitly setting this? Since, this will be my use case. With the option to set the FN manually whenever the user likes to set FN differently.

Eg. When N:Doe;J.;;; is specified FN is generated for you, even if FN is not specified, to the vCard output (.vcf): FN:J. Doe.

However, when both FN & N is not filled-in, only then return an error that FN is mandatory. Or is that already implemented like such 😕

@melroy89
Copy link

melroy89 commented Mar 4, 2019

@helveticadomes I changed my unit tester on the dev branch, can you pull the new changes from 2.0.0-dev? So I can validate the FN outcome.

@helveticadomes
Copy link
Author

Is it OK to assume that when N is filled-in, FN can be derived from that?

for me that make most sense, or do you think i should not do that?

it is implemented that:
if FN exist and N exist => keep both and do nothing to them
if FN exist but N dont exist => keep FN and do nothing with N
if FN & N dont exist => throw exception that FN is mandatory
if FN dont exist but N exist => silent create FN from N, and add it to the vcard

pull which changes where and how?

@melroy89
Copy link

melroy89 commented Mar 5, 2019

it is implemented that:
if FN exist and N exist => keep both and do nothing to them
if FN exist but N dont exist => keep FN and do nothing with N
if FN & N dont exist => throw exception that FN is mandatory
if FN dont exist but N exist => silent create FN from N, and add it to the vcard

That sounds good indeed!

pull which changes where and how?

You already did :). But how to trigger a rebuild on this PR 😕 (lack of knowledge of Github <> Travis integration I admit):
helveticadomes@4220a45

@melroy89
Copy link

melroy89 commented Mar 5, 2019

is it a good idea to also add a correct vcard file to assets? With correct I mean define the FN:.
https://github.com/helveticadomes/vcard/blob/feature-fixed-name-property/tests/assets/vcard.vcf

We can keep the current vcard asset as well (rename it?), since I think its a good test to validate if the jeroendesloovere/vcard parser is robust enough for parsing vcards files without FN (and only N) -> although its is an invalid Vcard file I think the parser should be robust.

src/VCard.php Outdated
if (count($found_name) == 0) {
throw VCardException::forRequiredProperty(new FullName('NoName'));
} else {
$found_fullname[] = new FullName(implode(' ', array_filter(array($found_name[0]->getPrefix(), $found_name[0]->getLastName(), $found_name[0]->getAdditional(), $found_name[0]->getFirstName(), $found_name[0]->getSuffix()))));
Copy link

Choose a reason for hiding this comment

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

Looking at the result of the fullname of the unit tester ran https://travis-ci.org/jeroendesloovere/vcard/jobs/502040710.

+FN:Mr. van den Berg Antoine Melroy\r\n

This is not correct.

I prefer: Prefix - firstname - additional - lastname - suffix order.

Which should result into:
+FN:Mr. Melroy Antoine van den Berg\r\n

I hope you agree as well regarding this.

Copy link
Author

Choose a reason for hiding this comment

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

i agree, fixed that & forcepush was to remove the commits created form a wrong rebase

@helveticadomes
Copy link
Author

lack of knowledge that describe exactly me :-D (git/github/travis)
if i assume right something need to be added to VCardTest.php because FN is added if only N exist.
but with all this dependencies it is something that begin slightly overstrain my capability

@melroy89
Copy link

melroy89 commented Mar 5, 2019

lack of knowledge that describe exactly me :-D (git/github/travis)
if i assume right something need to be added to VCardTest.php because FN is added if only N exist.
but with all this dependencies it is something that begin slightly overstrain my capability

No worries. I can either do it myself. Or better, guide you through the process to help you. So next time you do have the ability and skills to do it yourself 🙌 . I like the second approach, and help you.

EDIT: I think that unit testing is part of software development. So I think its a good think that can you write & execute them as well.

EDIT 2: I requested via @jeroendesloovere a gitter.im community project for vcard, so we could easily chat. Which may help in communication and learn faster.

Melroy van den Berg and others added 3 commits March 5, 2019 20:50
…g in the BDAY parser (change production code to fix). The testcases is correct.. 1 error left to fix as well
… mind to validate DateTimeValue class as well!
@melroy89
Copy link

melroy89 commented Mar 6, 2019

I fixed the testcases, found yet another bug in the DateTimeOrStringValue class. regarding the __toString() method.

The 'u' format (see Date format in php docs) will return zero's with a date! So that is definitely not the behavior you want.

Therefore I urge you to also look to the DateTimeValue which properly also need the same fix as DateTimeOrStringValue?

I also created a composer test, composer standard and finally a composer fix-standard. You're welcome 👍 .

src/VCard.php Outdated
if (count($found_name) == 0) {
throw VCardException::forRequiredProperty(new FullName('NoName'));
} else {
$found_fullname[] = new FullName(implode(' ', array_filter(array($found_name[0]->getPrefix(), $found_name[0]->getFirstName(), $found_name[0]->getAdditional(), $found_name[0]->getLastName(), $found_name[0]->getSuffix()))));

Choose a reason for hiding this comment

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

Can this be made more readable, for example something like:

$found_fullname[] = new FullName(implode(' ', array_filter(array(
    $found_name[0]->getPrefix(), 
    $found_name[0]->getFirstName(), 
    $found_name[0]->getAdditional(), 
    $found_name[0]->getLastName(), 
    $found_name[0]->getSuffix(),
))));

Copy link

Choose a reason for hiding this comment

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

I will fix this for helveticadomes.

composer.json Outdated
},
"scripts": {
"test": "phpunit tests",
"standard": "phpcs --standard=psr2 --extensions=php --warning-severity=0 --report=full 'src'",

Choose a reason for hiding this comment

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

Please use spaces not tabs just like the rest of the file

Copy link

Choose a reason for hiding this comment

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

ow oopsy thx

Choose a reason for hiding this comment

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

Your welcome

Copy link

Choose a reason for hiding this comment

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

Lessons learned: never use Gedit, Atom & vim all together 🤣

private $secondVCard;
protected static $secondVCard;

/** @var VCards: containing both first & second vcard together */

Choose a reason for hiding this comment

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

Choose a reason for hiding this comment

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

Also i'm not sure, but i don't believe the : is needed/allowed in the phpdoc specs

Copy link

Choose a reason for hiding this comment

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

ya ok its type Vcard.. I wanted to point out this variable stores two vcards together.

I don't know what I was thinking.. I will revert it.

@melroy89
Copy link

melroy89 commented Mar 7, 2019

@jeroendesloovere I think it's ready to be merged.

@@ -16,6 +16,7 @@ public function __construct(\DateTime $value)

public function __toString(): string
{
// TODO: possibly not in line with rfc6350
Copy link

Choose a reason for hiding this comment

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

However, somebody could also look to this toString() method. However, this can be done later as well (has nothing to do with the Name property fix)

Copy link

@melroy89 melroy89 Mar 7, 2019

Choose a reason for hiding this comment

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

Fixed. Thank you danger89 👍 Plus added an extra UT.

@melroy89
Copy link

melroy89 commented Mar 7, 2019

@helveticadomes Do you like to join the Gitter chat? https://gitter.im/vcard-php-library/community
This way we can easier help each other.

@melroy89
Copy link

melroy89 commented Mar 7, 2019

Ps.
@helveticadomes I don't get the "FullName is mandatory" exception when I use the getParameters(). But only with getContent().

@@ -17,7 +17,8 @@ public function __construct($value)
public function __toString(): string
{
if ($this->value instanceof \DateTime) {
return $this->value->format('u');
// According to DATE-AND-OR-TIME rfc6350 standard
return $this->value->format('Ymd\THis');

Choose a reason for hiding this comment

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

Copy link

@melroy89 melroy89 Mar 8, 2019

Choose a reason for hiding this comment

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

Z could be added indeed.

@@ -17,7 +17,8 @@ public function __construct($value)
public function __toString(): string
{
if ($this->value instanceof \DateTime) {
return $this->value->format('u');
// According to DATE-AND-OR-TIME rfc6350 standard
return $this->value->format('Ymd\THis');

Choose a reason for hiding this comment

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

I also want to raise a point for discussion, I see that in rfc6350 all the references to date and/or time basically say to use ISO 8601.
The thing is that php has a constant for ISO 8601 (DateTimeInterface::ATOM) which has the following syntax: Y-m-d\TH:i:sP (example: 2005-08-15T15:52:01+00:00), but this is different from the examples in rfc6350.
Personally i prefer the DateTimeInterface::ATOM style.
I'm interested in your opinions.

Copy link

@melroy89 melroy89 Mar 8, 2019

Choose a reason for hiding this comment

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

@to-be-the-best The RFC6350 says it's BASED ON that ISO standard: and that ISO standard mainly says this is the standard ISO notation: YYYY-MM-DD. Bear in mind that the ISO standard is very brought, and is not specific enough. That is why the RFC6350 is extended this ISO standard, to be more clear.

I'm just looking at the specification of that document:

To allow unambiguous
interpretation, a stand-alone TIME value is always preceded by a "T".

Examples for "date-and-or-time":

         19961022T140000

So I think the Z is debatable indeed.

And the ISO 8601 is even revised. And have two different versions ISO/DIS 8601-1 & ISO/DIS 8601-2.

TLDR;To conclude: Ymd\THis is OK according to the RFC6350 spec. The RFC standard is based on the ISO standard, but extends that, therefor I like to look to RFC standard only. Since RFC6350 is leading.
Finally, I think '\Z' can be added if you wish.

Copy link

Choose a reason for hiding this comment

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

Ps. plus we need to do manual test procedures to validate if this notation is indeed working for the most used applications (eg. Outlook, Google Contacts, iCloud, ..)

Copy link

@melroy89 melroy89 Mar 8, 2019

Choose a reason for hiding this comment

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

Ps. ps. Actually another related discussion I like to have instead, is how to define a PHP class that can be used to only output Ymd? Since the PHP DateTime() can be used to store both date & time. So I can only assume now that there WILL be a time included (also 00:00:00 could even be valid) and dump the full date time RFC standard notation into my vcard.

However, it would be nice to have an option to only a date (without time) and time (without date), with the proper toString() implementation for those two cases (together with the full date time case-> already implemented).

Use cases are: Birthday or anniversary, where just a date, without time is sufficient enough in most cases.

@helveticadomes
Copy link
Author

helveticadomes commented Mar 8, 2019

@helveticadomes I don't get the "FullName is mandatory" exception when I use the getParameters(). But only with getContent().

if you use getParameters() instead of getProperties() it is clear that you would not get the FullName exception ;-)

PS: i assume we need to add this expection also to VCardTest.

@to-be-the-best
Copy link

@helveticadomes I don't get the "FullName is mandatory" exception when I use the getParameters(). But only with getContent().

if you use getParameters() instead of getProperties() it is clear that you would not get the FullName exception ;-)

PS: i assume we need to add this expection also to VCardTest.

Indeed the expection needs tests

@melroy89
Copy link

melroy89 commented Mar 8, 2019

Currently its tested indirectly with several testcase like:

public function testVersionParameterParserGoodWeather(): void

As you can see these tests are not resulting into an exception/error. But indeed you want to have a test that proves the exception is actually trigger also (bad weather test).

@melroy89
Copy link

melroy89 commented Mar 8, 2019

Ready to merge now..? Please say yes ❤️

@melroy89
Copy link

melroy89 commented Mar 8, 2019

Create issue regarding DateTime to support also a single date or time object (with a proper toString() implementation for these two cases). Currently the DateTime can store both a date and time (even 00:00:00 is a valid time), therefor we always output the full date + time to the vcard file currently.

However Google Contacts can't handle this actually, despite the RFC standard. Regarding the birthday:
BDAY:19891207 results into (GOOD):
image

BDAY:19891207T104310 Results into (Not good 😭 , despite the standard followed):
image

Please, merge this PR, be more agile! 🍰 Separate issue is created: #148. Otherwise the merges/PRs are getting too big in my opinion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants