Skip to content

Commit 4fe278a

Browse files
committed
Issue #69: Handle grouped properties
As per RFC, properties can be grouped together by prefixing them with an arbitrary, alphanumeric value, followed by a full stop (.). Add support for this in the VCardParser class, and add unit tests accordingly.
1 parent b972ae4 commit 4fe278a

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

src/VCardParser.php

+16
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ protected function parse()
164164
} elseif (strtoupper($line) == "END:VCARD") {
165165
$this->vcardObjects[] = $cardData;
166166
} elseif (!empty($line)) {
167+
// Strip grouping information. We don't use the group names. We
168+
// simply use a list for entries that have multiple values.
169+
// As per RFC, group names are alphanumerical, and end with a
170+
// period (.).
171+
$line = preg_replace('/^\w+\./', '', $line);
172+
167173
$type = '';
168174
$value = '';
169175
@list($type, $value) = explode(':', $line, 2);
@@ -172,6 +178,16 @@ protected function parse()
172178
$element = strtoupper($types[0]);
173179

174180
array_shift($types);
181+
182+
// Normalize types. A type can either be a type-param directly,
183+
// or can be prefixed with "type=". E.g.: "INTERNET" or
184+
// "type=INTERNET".
185+
if (!empty($types)) {
186+
$types = array_map(function($type) {
187+
return preg_replace('/^type=/i', '', $type);
188+
}, $types);
189+
}
190+
175191
$i = 0;
176192
$rawValue = false;
177193
foreach ($types as $type) {

tests/VCardParserTest.php

+7-3
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,17 @@ public function testUrl()
153153
$this->assertEquals($parser->getCardAtIndex(0)->url['PREF;WORK'][0], 'http://work1.example.com');
154154
$this->assertEquals($parser->getCardAtIndex(0)->url['PREF;WORK'][1], 'http://work2.example.com');
155155
}
156-
156+
157157
public function testNote()
158158
{
159159
$vcard = new VCard();
160160
$vcard->addNote('This is a testnote');
161161
$parser = new VCardParser($vcard->buildVCard());
162-
162+
163163
$vcardMultiline = new VCard();
164164
$vcardMultiline->addNote("This is a multiline note\nNew line content!\r\nLine 2");
165165
$parserMultiline = new VCardParser($vcardMultiline->buildVCard());
166-
166+
167167
$this->assertEquals($parser->getCardAtIndex(0)->note, 'This is a testnote');
168168
$this->assertEquals(nl2br($parserMultiline->getCardAtIndex(0)->note), nl2br("This is a multiline note" . PHP_EOL . "New line content!" . PHP_EOL . "Line 2"));
169169
}
@@ -239,6 +239,10 @@ public function testFromFile()
239239
$this->assertEquals($cards[0]->firstname, "Wouter");
240240
$this->assertEquals($cards[0]->lastname, "Admiraal");
241241
$this->assertEquals($cards[0]->fullname, "Wouter Admiraal");
242+
// Check the parsing of grouped items as well, which are present in the
243+
// example file.
244+
$this->assertEquals($cards[0]->url['default'][0], 'http://example.com');
245+
$this->assertEquals($cards[0]->email['INTERNET'][0], '[email protected]');
242246
}
243247

244248
/**

tests/example.vcf

+4
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ VERSION:3.0
33
REV:2016-05-30T10:36:13Z
44
N;CHARSET=utf-8:Admiraal;Wouter;;;
55
FN;CHARSET=utf-8:Wouter Admiraal
6+
item1.EMAIL;type=INTERNET:[email protected]
7+
item1.X-ABLabel:$!<Email>!$
8+
item2.URL:http://example.com
9+
item2.X-ABLabel:$!<Home>!$
610
END:VCARD

0 commit comments

Comments
 (0)