Upgrading from vobject 2.x to 3.x
VObject 3.0 got a major overhaul, and much better built-in support for all kinds of properties and escaping.
This version fixes the most important bugs, specifically the issue #19.
To do this, a few backwards compatibility breaks had to be made. This document describes each of them, as well as all the new features.
Overview of new features
- Serializer now properly deals with escaped commas and semi-colons.
- Properties and Parameters now have a getParts() method to grab multiple values.
- You can now simply set PHP DateTime objects on DATE-TIME properties.
- Properties such as
CALSCALE,VERSIONandPRODIDwill automatically be added. - RFC6868 is used to serialize parameters.
- Methods to generate jCard and jCal objects.
- Parsing of vCard 2.1 is much, much better, including support for the broken
vCards Microsoft generates if the
FORGIVINGoption is on. - The
add()methods now return the objects that have been created. - A brand new parser that reads from streams, lowering memory usage.
- Components now have an easy to use
remove()method. - Every property, parameter and component has a reference to the document.
- Binary properties are automatically decoded.
Since sabre/vobject 3.1:
- Added a jCard and jCal parser.
- Using the
convert()method you can convert between vCard 2.1, 3.0 and 4.0. - A new CLI tool with
validate,repair,colorandconvertcommands.
Backwards compatibility breaks
Creating components
Before, it was possible to create components such as VEVENT, VTODO, etc
with this syntax:
<?php
$event = \Sabre\VObject\Component::create('VEVENT');
$event->summary = 'Birthday party!';
// Or:
$event = new \Sabre\VObject\Component('VEVENT');
$event->summary = 'Birthday party!';
?>
Neither of those are legal any longer. Components now must be created through the Document object.
Example:
<?php
$vcalendar = new \Sabre\VObject\Component\VCalendar();
$event = $vcalendar->createComponent('VEVENT');
$event->summary = 'Birthday party!';
?>
Or:
<?php
$vcalendar = new \Sabre\VObject\Component\VCalendar();
$vcalendar->add('VEVENT', [
'summary' => 'Birthday party!',
]);
?>
Creating properties
Creating properties works the exact same way.
Old:
<?php
$location = new \Sabre\VObject\Property('LOCATION', 'Home');
// Or:
$location = \Sabre\VObject\Property::create('LOCATION', 'Home');
?>
Now you must also use the document:
Example:
<?php
$card = new \Sabre\VObject\Component\VCard();
$location = $card->createProperty('LOCATION','Home');
?>
Note that in most cases, this syntax is highly recommended instead:
<?php
$card = new \Sabre\VObject\Component\VCard();
$location = $card->add('LOCATION','Home');
?>
In this case it doesn't make much of a difference, but when constructing highly complex objects with sub-components, this will make a big difference.
Component::children() and Property::parameters() return arrays.
Before VObject 3 they returned an ElementList.
The signature for DateTime::setDateTime has changed.
Before, you would use the following 4 syntaxes to set the date and time:
<?php
use Sabre\VObject\Property;
$now = new DateTime('now');
$dt = new Property\DateTime('DTSTART');
$dt->setDateTime($now, Property\DateTime::DATE); // Date only
$dt->setDateTime($now, Property\DateTime::LOCAL); // Floating time
$dt->setDateTime($now, Property\DateTime::UTC); // Convert to UTC
$dt->setDateTime($now, Property\DateTime::LOCALTZ); // Local to timezone information.
?>
This has completely changed:
<?php
// Date only
$now = new DateTime('now');
$dt = $calendar->create('DTSTART');
$dt->setValue($now);
$dt['VALUE'] = 'date';
// Floating time
$dt = $calendar->create('DTSTART');
$dt->setValue($now, $floating = true);
// Convert to UTC
$now->setTimeZone(\DateTimeZone('UTC'));
$dt = $calendar->create('DTSTART');
$dt->setValue($now);
// Local time + timezone information
$dt = $calendar->create('DTSTART');
$dt->setValue($now);
?>
Note that the preceding examples are all a bit convoluted. In most cases you just want to do something like:
<?php
// Assuming this a vevent
$event->DTSTART = $now;
?>
In addition, the MultiDateTime property is no more, and its methods are
simply merged into DateTime.
The $value property is now protected everywhere.
Both the Property and the Parameter classes had a public $value property,
which allowed you to retrieve the string value for either of those.
This is now protected, so you must access it in this manner:
<?php
// Assuming $prop is a property object.
$prop->setValue('Birthday');
echo $prop->getValue();
?>
// For properties that have more than 1 value, you can use setParts and
getParts:
<?php
$org->setParts(['Company', 'Department']);
print_r($org->getParts());
?>
Binary properties are automatically de- and encoded.
The ATTACH, LOGO and PHOTO properties now automatically de- and encode
their binary values. In vObject 2 they were accessed by their raw base64
values.
Components and documents get injected with default properties.
When creating a new VCalendar, it will automatically get the VERSION,
CALSCALE and PRODID properties.
If you were adding your own with this syntax:
<?php
$calendar = new Sabre\VObject\Component\VCalendar();
$calendar->VERSION = '2.0';
?>
Then nothing will go wrong, and the properties will simply be overwritten.
However, if you used add() before in this manner:
<?php
$calendar = new Sabre\VObject\Component\VCalendar();
$calendar->add('version', '2.0');
?>
You will end up with 2 VERSION properties, making the document invalid.
componentMap and propertyMap properties have moved.
When you wanted to automatically map certain components or properties to
certain PHP classes, you could do so with Component::$componentMap and
Property::$propertyMap.
These properties have now moved to the document classes:
Component\VCalendar::$propertyMapComponent\VCalendar::$componentMapComponent\VCard::$propertyMapComponent\VCard::$componentMap
sabre