Skip to content

Commit

Permalink
restrict vcard fields by version
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreLebedel committed Oct 25, 2024
1 parent 6633c0d commit bcd130e
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 27 deletions.
106 changes: 101 additions & 5 deletions src/VCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,117 @@

class VCard
{
public ?string $version = null;

public stdClass $formattedData;

public stdClass $rawData;

public stdClass $unexpectedData;
public stdClass $invalidData;

public stdClass $unprocessedData;

public function __construct()
{
$this->formattedData = new stdClass();
$this->formattedData = new stdClass;
$this->rawData = new stdClass;
$this->unexpectedData = new stdClass;
$this->invalidData = new stdClass;
$this->unprocessedData = new stdClass;
}

public function setVersion(string $version): self
{
$this->version = $version;
$this->initVersionData();

return $this;
}

public function getVersion(): string
public function getVersion(): ?string
{
return $this->formattedData->version ?? '4.0';
return $this->version;
}

public function initVersionData(): self
{
if (! $this->version) {
return $this;
}

$dataFields = [
'fn' => 'fullName',
'n' => 'name',
'adr' => 'addresses',
'bday' => 'birthday',
'email' => 'emails',
'geo' => 'geo',
'key' => 'key',
'logo' => 'logo',
'n' => 'name',
'note' => 'note',
'org' => 'organization',
'photo' => 'photo',
'rev' => 'revision',
'role' => 'role',
'sound' => 'sound',
'tel' => 'phones',
'title' => 'title',
'tz' => 'timezone',
'uid' => 'uid',
'url' => 'url',
'version' => 'version',
];

if ($this->version == '2.1') {
$dataFields += [
'agent' => 'agent',
'label' => 'label',
'lang' => 'lang',
'mailer' => 'mailer',
];

} elseif ($this->version == '3.0') {
$dataFields += [
'agent' => 'agent',
'categories' => 'categories',
'class' => 'class',
'impp' => 'impp',
'label' => 'label',
'mailer' => 'mailer',
'name' => 'name',
'nickname' => 'nicknames',
'prodid' => 'prodid',
'profile' => 'profile',
'sort-string' => 'sort-string',
'source' => 'source',
];

} elseif ($this->version == '4.0') {
$dataFields += [
'anniversary' => 'anniversary',
'caladruri' => 'caladruri',
'caluri' => 'caluri',
'categories' => 'categories',
'clientpidmap' => 'clientpidmap',
'fburl' => 'fburl',
'gender' => 'gender',
'impp' => 'impp',
'kind' => 'kind',
'lang' => 'langs',
'member' => 'member',
'nickname' => 'nicknames',
'prodid' => 'prodid',
'related' => 'related',
'source' => 'source',
'xml' => 'xml',
];
}

foreach ($dataFields as $field => $alias) {
$this->formattedData->{$alias} = null;
$this->rawData->{$field} = null;
}

return $this;
}
}
38 changes: 21 additions & 17 deletions src/VCardField.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class VCardField

protected $isMultiple = false;

protected $isUnexpected = false;
protected $isUnprocessed = false;

public function __construct(public string $rawContents)
{
Expand Down Expand Up @@ -87,15 +87,6 @@ protected function parseAttributes()
$this->attributes = $newAttributes;
}

public function version(): self
{
$this->isString = true;
$this->formattedValue = $this->value;
$this->rawValue = $this->value;

return $this;
}

public function string(): self
{
$this->isString = true;
Expand Down Expand Up @@ -237,9 +228,10 @@ public function timezone(): self
return $this;
}

public function as(string $formattedName) :self
public function as(string $formattedName): self
{
$this->formattedName = $formattedName;

return $this;
}

Expand All @@ -254,8 +246,8 @@ public function in(array $stringPossibilities): self

public function addAttribute(string $attribute, array $constrainedBy = []): self
{
if($attribute=='type' && array_key_exists('type', $this->attributes)){
if(in_array('pref', array_map('strtolower', $this->attributes['type']))){
if ($attribute == 'type' && array_key_exists('type', $this->attributes)) {
if (in_array('pref', array_map('strtolower', $this->attributes['type']))) {
$this->formattedValue->attributes['pref'] = 1;
}
}
Expand Down Expand Up @@ -296,17 +288,29 @@ public function addAttribute(string $attribute, array $constrainedBy = []): self
return $this;
}

public function unexpected(): self
public function unprocecced(): self
{
$this->isUnexpected = true;
$this->isUnprocessed = true;

return $this;
}

public function render(VCard $vCard)
{
if ($this->isUnexpected) {
$vCard->unexpectedData->{$this->name} = $this->rawContents;
if ($this->isUnprocessed) {
$vCard->unprocessedData->{$this->name} = $this->rawContents;

return;
}

if (! property_exists($vCard->rawData, $this->name)) {
$vCard->invalidData->{$this->name} = $this->rawContents;

return;
}

if (! property_exists($vCard->formattedData, $this->formattedName)) {
$vCard->invalidData->{$this->name} = '[formatted] '.$this->rawContents;

return;
}
Expand Down
14 changes: 9 additions & 5 deletions src/VCardParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,28 +207,32 @@ protected function parseLine(int $lineNumber, string $lineContents): void
'name',
'units1',
'units2',
])->addAttribute('type'),
])->addAttribute('type')->as('organization'),
'photo' => $field->uri()->addAttribute('type'),
'prodid' => $field->string(),
'profile' => $field->string(),
'related' => $field->uri()->addAttribute('type'),
'rev' => $field->datetime(),
'rev' => $field->datetime()->as('revision'),
'role' => $field->string()->addAttribute('type'),
'sort-string' => $field->string(),
'sound' => $field->uri()->addAttribute('type'),
'source' => $field->uri(),
'tel' => $field->object()->multiple()->addAttribute('type', ['home', 'msg', 'work', 'pref', 'voice', 'fax', 'cell', 'video', 'pager', 'bbs', 'modem', 'car', 'isdn', 'pcs'])->as('phones'),
'title' => $field->string()->addAttribute('type'),
'tz' => $field->timezone()->addAttribute('type'),
'tz' => $field->timezone()->addAttribute('type')->as('timezone'),
'uid' => $field->string()->ltrim(['urn:uuid:']),
'url' => $field->uri()->addAttribute('type'),
'version' => $field->version(),
'version' => $field->string(),
'xml' => $field->string(),
default => $field->unexpected(),
default => $field->unprocecced(),
};

//dump($field);

if ($field->name == 'version') {
$this->getVCard()->setVersion($field->value);
}

$field->render($this->getVCard());
}
}

0 comments on commit bcd130e

Please sign in to comment.