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
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,19 @@ More info on how to work with GitHub on help.github.com.
We use [squizlabs/php_codesniffer](https://packagist.org/packages/squizlabs/php_codesniffer) to maintain the code standards.
Type the following to execute them:
```bash
# To view the code errors
vendor/bin/phpcs --standard=psr2 --extensions=php --warning-severity=0 --report=full "src"
# To view the code violation errors
composer standard

# OR to fix the code errors
vendor/bin/phpcbf --standard=psr2 --extensions=php --warning-severity=0 --report=full "src"
# OR to fix the code violation errors
composer fix-standard
```
> [Read documentation about the code standards](https://github.com/squizlabs/PHP_CodeSniffer/wiki)

### Unit Tests

We have build in tests, type the following to execute them:
We have build-in tests using [PHPUnit](https://phpunit.readthedocs.io/en/8.0/writing-tests-for-phpunit.html), type the following to execute them:
```bash
vendor/bin/phpunit tests
composer test
```

## Credits
Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,10 @@
},
"autoload": {
"psr-4": { "JeroenDesloovere\\VCard\\": "src/" }
},
"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 🤣

"fix-standard": "phpcbf --standard=psr2 --extensions=php --warning-severity=0 --report=full 'src'"
}
}
7 changes: 7 additions & 0 deletions src/Exception/VCardException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@

class VCardException extends \Exception
{
public static function forRequiredProperty(PropertyInterface $property): self
{
return new self(
'The property "' . get_class($property) . '" is mandatory, and you need to add it once.'
);
}

public static function forExistingProperty(PropertyInterface $property): self
{
return new self(
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Property/NameParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class NameParser extends PropertyParser implements NodeParserInterface
{
public function parseVcfString(string $value, array $parameters = []): NodeInterface
{
@list($firstName, $additional, $lastName, $prefix, $suffix) = explode(';', $value);
@list($lastName, $firstName, $additional, $prefix, $suffix) = explode(';', $value);

$this->convertEmptyStringToNull([
$lastName,
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/VcfParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private function parseVCardContentLine(string $line, VCard &$vCard): void
// As per RFC, group names are alphanumerical, and end with a
// period (.).
$line = preg_replace('/^\w+\./', '', trim($line));

/**
* @var string $node
* @var string $value
Expand Down
4 changes: 2 additions & 2 deletions src/Property/Name.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
final class Name implements PropertyInterface, NodeInterface
{
/** @var null|string */
private $additional;
private $lastName;

/** @var null|string */
private $firstName;

/** @var null|string */
private $lastName;
private $additional;

/** @var null|string */
private $prefix;
Expand Down
3 changes: 2 additions & 1 deletion src/Property/Value/DateTimeOrStringValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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.

}

return $this->value;
Expand Down
1 change: 1 addition & 0 deletions src/Property/Value/DateTimeValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.

return $this->value->format('u');
}

Expand Down
30 changes: 29 additions & 1 deletion src/VCard.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php

declare(strict_types=1);

namespace JeroenDesloovere\VCard;
Expand Down Expand Up @@ -160,9 +159,38 @@ public function getParameters(string $filterByPropertyParameterClass = null): ar
});
}

/**
* @param string $forPropertyClass
* @return array
* @throws VCardException
*/
public function getProperties(string $forPropertyClass = null): array
{
if ($forPropertyClass === null) {
$array = $this->properties;
//make empty array var for each required Property or Property you need to work with
$found_fullname = $found_name = $others = [];
foreach ($array as $value) {
//search if property exist and add it to the defined array var, else add it to the others array
if ($value instanceof FullName) {
$found_fullname[] = $value;
} elseif ($value instanceof Name) {
$found_name[] = $value;
} else {
$others[] = $value;
}
}
//check for empty and throw exception, if it can not be generated by existing fields
if (count($found_fullname) == 0) {
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.

}
}
$array = array_merge($found_fullname, $found_name, $others);
$this->properties = $array;

return $this->properties;
}

Expand Down
Loading