/** * Handles conversion of a single property. * * @param Component\VCard $input * @param Component\VCard $output * @param Property $property * @param int $targetVersion * @return void */ protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) { // Skipping these, those are automatically added. if (in_array($property->name, array('VERSION', 'PRODID'))) { return; } $parameters = $property->parameters(); $valueType = null; if (isset($parameters['VALUE'])) { $valueType = $parameters['VALUE']->getValue(); unset($parameters['VALUE']); } if (!$valueType) { $valueType = $property->getValueType(); } $newProperty = null; if ($targetVersion === Document::VCARD30) { if ($property instanceof Property\Uri && in_array($property->name, array('PHOTO', 'LOGO', 'SOUND'))) { $newProperty = $this->convertUriToBinary($output, $property, $parameters); } elseif ($property->name === 'KIND') { switch (strtolower($property->getValue())) { case 'org': // OS X addressbook property. $newProperty = $output->createProperty('X-ABSHOWAS', 'COMPANY'); break; case 'individual': // Individual is implied, so we can just skip it. return; case 'group': // OS X addressbook property $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND', 'GROUP'); break; } } } elseif ($targetVersion === Document::VCARD40) { // These properties were removed in vCard 4.0 if (in_array($property->name, array('NAME', 'MAILER', 'LABEL', 'CLASS'))) { return; } if ($property instanceof Property\Binary) { $newProperty = $this->convertBinaryToUri($output, $property, $parameters); } else { switch ($property->name) { case 'X-ABSHOWAS': if (strtoupper($property->getValue()) === 'COMPANY') { $newProperty = $output->createProperty('KIND', 'org'); } break; case 'X-ADDRESSBOOKSERVER-KIND': if (strtoupper($property->getValue()) === 'GROUP') { $newProperty = $output->createProperty('KIND', 'group'); } break; } } } if (is_null($newProperty)) { $newProperty = $output->createProperty($property->name, $property->getParts(), array(), $valueType); } // set property group $newProperty->group = $property->group; if ($targetVersion === Document::VCARD40) { $this->convertParameters40($newProperty, $parameters); } else { $this->convertParameters30($newProperty, $parameters); } // Lastly, we need to see if there's a need for a VALUE parameter. // // We can do that by instantating a empty property with that name, and // seeing if the default valueType is identical to the current one. $tempProperty = $output->createProperty($newProperty->name); if ($tempProperty->getValueType() !== $newProperty->getValueType()) { $newProperty['VALUE'] = $newProperty->getValueType(); } $output->add($newProperty); }
/** * Handles conversion of a single property. * * @param Component\VCard $input * @param Component\VCard $output * @param Property $property * @param int $targetVersion * @return void */ protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) { // Skipping these, those are automatically added. if (in_array($property->name, array('VERSION', 'PRODID'))) { return; } $parameters = $property->parameters(); $valueType = null; if (isset($parameters['VALUE'])) { $valueType = $parameters['VALUE']->getValue(); unset($parameters['VALUE']); } if (!$valueType) { $valueType = $property->getValueType(); } $newProperty = $output->createProperty($property->name, $property->getParts(), array(), $valueType); if ($targetVersion === Document::VCARD30) { if ($property instanceof Property\Uri && in_array($property->name, array('PHOTO', 'LOGO', 'SOUND'))) { $newProperty = $this->convertUriToBinary($output, $newProperty, $parameters); } elseif ($property instanceof Property\VCard\DateAndOrTime) { // In vCard 4, the birth year may be optional. This is not the // case for vCard 3. Apple has a workaround for this that // allows applications that support Apple's extension still // omit birthyears in vCard 3, but applications that do not // support this, will just use a random birthyear. We're // choosing 1604 for the birthyear, because that's what apple // uses. $parts = DateTimeParser::parseVCardDateTime($property->getValue()); if (is_null($parts['year'])) { $newValue = '1604-' . $parts['month'] . '-' . $parts['date']; $newProperty->setValue($newValue); $newProperty['X-APPLE-OMIT-YEAR'] = '1604'; } if ($newProperty->name == 'ANNIVERSARY') { // Microsoft non-standard anniversary $newProperty->name = 'X-ANNIVERSARY'; // We also need to add a new apple property for the same // purpose. This apple property needs a 'label' in the same // group, so we first need to find a groupname that doesn't // exist yet. $x = 1; while ($output->select('ITEM' . $x . '.')) { $x++; } $output->add('ITEM' . $x . '.X-ABDATE', $newProperty->getValue(), array('VALUE' => 'DATE-AND-OR-TIME')); $output->add('ITEM' . $x . '.X-ABLABEL', '_$!<Anniversary>!$_'); } } elseif ($property->name === 'KIND') { switch (strtolower($property->getValue())) { case 'org': // vCard 3.0 does not have an equivalent to KIND:ORG, // but apple has an extension that means the same // thing. $newProperty = $output->createProperty('X-ABSHOWAS', 'COMPANY'); break; case 'individual': // Individual is implicit, so we skip it. return; case 'group': // OS X addressbook property $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND', 'GROUP'); break; } } } elseif ($targetVersion === Document::VCARD40) { // These properties were removed in vCard 4.0 if (in_array($property->name, array('NAME', 'MAILER', 'LABEL', 'CLASS'))) { return; } if ($property instanceof Property\Binary) { $newProperty = $this->convertBinaryToUri($output, $newProperty, $parameters); } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) { // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR', // then we're stripping the year from the vcard 4 value. $parts = DateTimeParser::parseVCardDateTime($property->getValue()); if ($parts['year'] === $property['X-APPLE-OMIT-YEAR']->getValue()) { $newValue = '--' . $parts['month'] . '-' . $parts['date']; $newProperty->setValue($newValue); } // Regardless if the year matched or not, we do need to strip // X-APPLE-OMIT-YEAR. unset($parameters['X-APPLE-OMIT-YEAR']); } switch ($property->name) { case 'X-ABSHOWAS': if (strtoupper($property->getValue()) === 'COMPANY') { $newProperty = $output->createProperty('KIND', 'ORG'); } break; case 'X-ADDRESSBOOKSERVER-KIND': if (strtoupper($property->getValue()) === 'GROUP') { $newProperty = $output->createProperty('KIND', 'GROUP'); } break; case 'X-ANNIVERSARY': $newProperty->name = 'ANNIVERSARY'; // If we already have an anniversary property with the same // value, ignore. foreach ($output->select('ANNIVERSARY') as $anniversary) { if ($anniversary->getValue() === $newProperty->getValue()) { return; } } break; case 'X-ABDATE': // Find out what the label was, if it exists. if (!$property->group) { break; } $label = $input->{$property->group . '.X-ABLABEL'}; // We only support converting anniversaries. if ($label->getValue() !== '_$!<Anniversary>!$_') { break; } // If we already have an anniversary property with the same // value, ignore. foreach ($output->select('ANNIVERSARY') as $anniversary) { if ($anniversary->getValue() === $newProperty->getValue()) { return; } } $newProperty->name = 'ANNIVERSARY'; break; // Apple's per-property label system. // Apple's per-property label system. case 'X-ABLABEL': if ($newProperty->getValue() === '_$!<Anniversary>!$_') { // We can safely remove these, as they are converted to // ANNIVERSARY properties. return; } break; } } // set property group $newProperty->group = $property->group; if ($targetVersion === Document::VCARD40) { $this->convertParameters40($newProperty, $parameters); } else { $this->convertParameters30($newProperty, $parameters); } // Lastly, we need to see if there's a need for a VALUE parameter. // // We can do that by instantating a empty property with that name, and // seeing if the default valueType is identical to the current one. $tempProperty = $output->createProperty($newProperty->name); if ($tempProperty->getValueType() !== $newProperty->getValueType()) { $newProperty['VALUE'] = $newProperty->getValueType(); } $output->add($newProperty); }
/** * Handles conversion of a single property. * * @param Component\VCard $input * @param Component\VCard $output * @param Property $property * @param int $targetVersion * @return void */ protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) { // Skipping these, those are automatically added. if (in_array($property->name, ['VERSION', 'PRODID'])) { return; } $parameters = $property->parameters(); $valueType = null; if (isset($parameters['VALUE'])) { $valueType = $parameters['VALUE']->getValue(); unset($parameters['VALUE']); } if (!$valueType) { $valueType = $property->getValueType(); } $newProperty = null; if ($targetVersion === Document::VCARD30) { if ($property instanceof Property\Uri && in_array($property->name, ['PHOTO', 'LOGO', 'SOUND'])) { $newProperty = $this->convertUriToBinary($output, $property, $parameters); } elseif ($property instanceof Property\VCard\DateAndOrTime) { // In vCard 4, the birth year may be optional. This is not the // case for vCard 3. Apple has a workaround for this that // allows applications that support Apple's extension still // omit birthyears in vCard 3, but applications that do not // support this, will just use a random birthyear. We're // choosing 1604 for the birthyear, because that's what apple // uses. $parts = DateTimeParser::parseVCardDateTime($property->getValue()); if (is_null($parts['year'])) { $newValue = '1604-' . $parts['month'] . '-' . $parts['date']; $newProperty = $output->createProperty($property->name, $newValue, ['X-APPLE-OMIT-YEAR' => '1604'], $valueType); } } elseif ($property->name === 'KIND') { switch (strtolower($property->getValue())) { case 'org': // OS X addressbook property. $newProperty = $output->createProperty('X-ABSHOWAS', 'COMPANY'); break; case 'individual': // Individual is implied, so we can just skip it. return; case 'group': // OS X addressbook property $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND', 'GROUP'); break; } } } elseif ($targetVersion === Document::VCARD40) { // These properties were removed in vCard 4.0 if (in_array($property->name, ['NAME', 'MAILER', 'LABEL', 'CLASS'])) { return; } if ($property instanceof Property\Binary) { $newProperty = $this->convertBinaryToUri($output, $property, $parameters); } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) { // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR', // then we're stripping the year from the vcard 4 value. $parts = DateTimeParser::parseVCardDateTime($property->getValue()); if ($parts['year'] === $property['X-APPLE-OMIT-YEAR']->getValue()) { $newValue = '--' . $parts['month'] . '-' . $parts['date']; $newProperty = $output->createProperty($property->name, $newValue, [], $valueType); } // Regardless if the year matched or not, we do need to strip // X-APPLE-OMIT-YEAR. unset($parameters['X-APPLE-OMIT-YEAR']); } else { switch ($property->name) { case 'X-ABSHOWAS': if (strtoupper($property->getValue()) === 'COMPANY') { $newProperty = $output->createProperty('KIND', 'org'); } break; case 'X-ADDRESSBOOKSERVER-KIND': if (strtoupper($property->getValue()) === 'GROUP') { $newProperty = $output->createProperty('KIND', 'group'); } break; } } } if (is_null($newProperty)) { $newProperty = $output->createProperty($property->name, $property->getParts(), [], $valueType); } // set property group $newProperty->group = $property->group; if ($targetVersion === Document::VCARD40) { $this->convertParameters40($newProperty, $parameters); } else { $this->convertParameters30($newProperty, $parameters); } // Lastly, we need to see if there's a need for a VALUE parameter. // // We can do that by instantating a empty property with that name, and // seeing if the default valueType is identical to the current one. $tempProperty = $output->createProperty($newProperty->name); if ($tempProperty->getValueType() !== $newProperty->getValueType()) { $newProperty['VALUE'] = $newProperty->getValueType(); } $output->add($newProperty); }