xref: /plugin/davcal/vendor/sabre/vobject/lib/VCardConverter.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\VObject;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehler/**
6*a1a3b679SAndreas Boehler * This utility converts vcards from one version to another.
7*a1a3b679SAndreas Boehler *
8*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
9*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
10*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
11*a1a3b679SAndreas Boehler */
12*a1a3b679SAndreas Boehlerclass VCardConverter {
13*a1a3b679SAndreas Boehler
14*a1a3b679SAndreas Boehler    /**
15*a1a3b679SAndreas Boehler     * Converts a vCard object to a new version.
16*a1a3b679SAndreas Boehler     *
17*a1a3b679SAndreas Boehler     * targetVersion must be one of:
18*a1a3b679SAndreas Boehler     *   Document::VCARD21
19*a1a3b679SAndreas Boehler     *   Document::VCARD30
20*a1a3b679SAndreas Boehler     *   Document::VCARD40
21*a1a3b679SAndreas Boehler     *
22*a1a3b679SAndreas Boehler     * Currently only 3.0 and 4.0 as input and output versions.
23*a1a3b679SAndreas Boehler     *
24*a1a3b679SAndreas Boehler     * 2.1 has some minor support for the input version, it's incomplete at the
25*a1a3b679SAndreas Boehler     * moment though.
26*a1a3b679SAndreas Boehler     *
27*a1a3b679SAndreas Boehler     * If input and output version are identical, a clone is returned.
28*a1a3b679SAndreas Boehler     *
29*a1a3b679SAndreas Boehler     * @param Component\VCard $input
30*a1a3b679SAndreas Boehler     * @param int $targetVersion
31*a1a3b679SAndreas Boehler     */
32*a1a3b679SAndreas Boehler    public function convert(Component\VCard $input, $targetVersion) {
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehler        $inputVersion = $input->getDocumentType();
35*a1a3b679SAndreas Boehler        if ($inputVersion===$targetVersion) {
36*a1a3b679SAndreas Boehler            return clone $input;
37*a1a3b679SAndreas Boehler        }
38*a1a3b679SAndreas Boehler
39*a1a3b679SAndreas Boehler        if (!in_array($inputVersion, array(Document::VCARD21, Document::VCARD30, Document::VCARD40))) {
40*a1a3b679SAndreas Boehler            throw new \InvalidArgumentException('Only vCard 2.1, 3.0 and 4.0 are supported for the input data');
41*a1a3b679SAndreas Boehler        }
42*a1a3b679SAndreas Boehler        if (!in_array($targetVersion, array(Document::VCARD30, Document::VCARD40))) {
43*a1a3b679SAndreas Boehler            throw new \InvalidArgumentException('You can only use vCard 3.0 or 4.0 for the target version');
44*a1a3b679SAndreas Boehler        }
45*a1a3b679SAndreas Boehler
46*a1a3b679SAndreas Boehler        $newVersion = $targetVersion===Document::VCARD40?'4.0':'3.0';
47*a1a3b679SAndreas Boehler
48*a1a3b679SAndreas Boehler        $output = new Component\VCard(array(
49*a1a3b679SAndreas Boehler            'VERSION' => $newVersion,
50*a1a3b679SAndreas Boehler        ));
51*a1a3b679SAndreas Boehler
52*a1a3b679SAndreas Boehler        foreach($input->children as $property) {
53*a1a3b679SAndreas Boehler
54*a1a3b679SAndreas Boehler            $this->convertProperty($input, $output, $property, $targetVersion);
55*a1a3b679SAndreas Boehler
56*a1a3b679SAndreas Boehler        }
57*a1a3b679SAndreas Boehler
58*a1a3b679SAndreas Boehler        return $output;
59*a1a3b679SAndreas Boehler
60*a1a3b679SAndreas Boehler    }
61*a1a3b679SAndreas Boehler
62*a1a3b679SAndreas Boehler    /**
63*a1a3b679SAndreas Boehler     * Handles conversion of a single property.
64*a1a3b679SAndreas Boehler     *
65*a1a3b679SAndreas Boehler     * @param Component\VCard $input
66*a1a3b679SAndreas Boehler     * @param Component\VCard $output
67*a1a3b679SAndreas Boehler     * @param Property $property
68*a1a3b679SAndreas Boehler     * @param int $targetVersion
69*a1a3b679SAndreas Boehler     * @return void
70*a1a3b679SAndreas Boehler     */
71*a1a3b679SAndreas Boehler    protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) {
72*a1a3b679SAndreas Boehler
73*a1a3b679SAndreas Boehler        // Skipping these, those are automatically added.
74*a1a3b679SAndreas Boehler        if (in_array($property->name, array('VERSION', 'PRODID'))) {
75*a1a3b679SAndreas Boehler            return;
76*a1a3b679SAndreas Boehler        }
77*a1a3b679SAndreas Boehler
78*a1a3b679SAndreas Boehler        $parameters = $property->parameters();
79*a1a3b679SAndreas Boehler        $valueType = null;
80*a1a3b679SAndreas Boehler        if (isset($parameters['VALUE'])) {
81*a1a3b679SAndreas Boehler            $valueType = $parameters['VALUE']->getValue();
82*a1a3b679SAndreas Boehler            unset($parameters['VALUE']);
83*a1a3b679SAndreas Boehler        }
84*a1a3b679SAndreas Boehler        if (!$valueType) {
85*a1a3b679SAndreas Boehler            $valueType = $property->getValueType();
86*a1a3b679SAndreas Boehler        }
87*a1a3b679SAndreas Boehler        $newProperty = $output->createProperty(
88*a1a3b679SAndreas Boehler            $property->name,
89*a1a3b679SAndreas Boehler            $property->getParts(),
90*a1a3b679SAndreas Boehler            array(), // parameters will get added a bit later.
91*a1a3b679SAndreas Boehler            $valueType
92*a1a3b679SAndreas Boehler        );
93*a1a3b679SAndreas Boehler
94*a1a3b679SAndreas Boehler
95*a1a3b679SAndreas Boehler        if ($targetVersion===Document::VCARD30) {
96*a1a3b679SAndreas Boehler
97*a1a3b679SAndreas Boehler            if ($property instanceof Property\Uri && in_array($property->name, array('PHOTO','LOGO','SOUND'))) {
98*a1a3b679SAndreas Boehler
99*a1a3b679SAndreas Boehler                $newProperty = $this->convertUriToBinary($output, $newProperty);
100*a1a3b679SAndreas Boehler
101*a1a3b679SAndreas Boehler            } elseif ($property instanceof Property\VCard\DateAndOrTime) {
102*a1a3b679SAndreas Boehler
103*a1a3b679SAndreas Boehler                // In vCard 4, the birth year may be optional. This is not the
104*a1a3b679SAndreas Boehler                // case for vCard 3. Apple has a workaround for this that
105*a1a3b679SAndreas Boehler                // allows applications that support Apple's extension still
106*a1a3b679SAndreas Boehler                // omit birthyears in vCard 3, but applications that do not
107*a1a3b679SAndreas Boehler                // support this, will just use a random birthyear. We're
108*a1a3b679SAndreas Boehler                // choosing 1604 for the birthyear, because that's what apple
109*a1a3b679SAndreas Boehler                // uses.
110*a1a3b679SAndreas Boehler                $parts = DateTimeParser::parseVCardDateTime($property->getValue());
111*a1a3b679SAndreas Boehler                if (is_null($parts['year'])) {
112*a1a3b679SAndreas Boehler                    $newValue = '1604-' . $parts['month'] . '-' . $parts['date'];
113*a1a3b679SAndreas Boehler                    $newProperty->setValue($newValue);
114*a1a3b679SAndreas Boehler                    $newProperty['X-APPLE-OMIT-YEAR'] = '1604';
115*a1a3b679SAndreas Boehler                }
116*a1a3b679SAndreas Boehler
117*a1a3b679SAndreas Boehler                if ($newProperty->name == 'ANNIVERSARY') {
118*a1a3b679SAndreas Boehler                    // Microsoft non-standard anniversary
119*a1a3b679SAndreas Boehler                    $newProperty->name = 'X-ANNIVERSARY';
120*a1a3b679SAndreas Boehler
121*a1a3b679SAndreas Boehler                    // We also need to add a new apple property for the same
122*a1a3b679SAndreas Boehler                    // purpose. This apple property needs a 'label' in the same
123*a1a3b679SAndreas Boehler                    // group, so we first need to find a groupname that doesn't
124*a1a3b679SAndreas Boehler                    // exist yet.
125*a1a3b679SAndreas Boehler                    $x = 1;
126*a1a3b679SAndreas Boehler                    while($output->select('ITEM' . $x . '.')) {
127*a1a3b679SAndreas Boehler                        $x++;
128*a1a3b679SAndreas Boehler                    }
129*a1a3b679SAndreas Boehler                    $output->add('ITEM' . $x . '.X-ABDATE', $newProperty->getValue(), array('VALUE' => 'DATE-AND-OR-TIME'));
130*a1a3b679SAndreas Boehler                    $output->add('ITEM' . $x . '.X-ABLABEL', '_$!<Anniversary>!$_');
131*a1a3b679SAndreas Boehler                }
132*a1a3b679SAndreas Boehler
133*a1a3b679SAndreas Boehler            } elseif ($property->name === 'KIND') {
134*a1a3b679SAndreas Boehler
135*a1a3b679SAndreas Boehler                switch(strtolower($property->getValue())) {
136*a1a3b679SAndreas Boehler                    case 'org' :
137*a1a3b679SAndreas Boehler                        // vCard 3.0 does not have an equivalent to KIND:ORG,
138*a1a3b679SAndreas Boehler                        // but apple has an extension that means the same
139*a1a3b679SAndreas Boehler                        // thing.
140*a1a3b679SAndreas Boehler                        $newProperty = $output->createProperty('X-ABSHOWAS','COMPANY');
141*a1a3b679SAndreas Boehler                        break;
142*a1a3b679SAndreas Boehler
143*a1a3b679SAndreas Boehler                    case 'individual' :
144*a1a3b679SAndreas Boehler                        // Individual is implicit, so we skip it.
145*a1a3b679SAndreas Boehler                        return;
146*a1a3b679SAndreas Boehler
147*a1a3b679SAndreas Boehler                    case 'group' :
148*a1a3b679SAndreas Boehler                        // OS X addressbook property
149*a1a3b679SAndreas Boehler                        $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND','GROUP');
150*a1a3b679SAndreas Boehler                        break;
151*a1a3b679SAndreas Boehler                }
152*a1a3b679SAndreas Boehler
153*a1a3b679SAndreas Boehler
154*a1a3b679SAndreas Boehler            }
155*a1a3b679SAndreas Boehler
156*a1a3b679SAndreas Boehler        } elseif ($targetVersion===Document::VCARD40) {
157*a1a3b679SAndreas Boehler
158*a1a3b679SAndreas Boehler            // These properties were removed in vCard 4.0
159*a1a3b679SAndreas Boehler            if (in_array($property->name, array('NAME', 'MAILER', 'LABEL', 'CLASS'))) {
160*a1a3b679SAndreas Boehler                return;
161*a1a3b679SAndreas Boehler            }
162*a1a3b679SAndreas Boehler
163*a1a3b679SAndreas Boehler            if ($property instanceof Property\Binary) {
164*a1a3b679SAndreas Boehler
165*a1a3b679SAndreas Boehler                $newProperty = $this->convertBinaryToUri($output, $newProperty, $parameters);
166*a1a3b679SAndreas Boehler
167*a1a3b679SAndreas Boehler            } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) {
168*a1a3b679SAndreas Boehler
169*a1a3b679SAndreas Boehler                // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR',
170*a1a3b679SAndreas Boehler                // then we're stripping the year from the vcard 4 value.
171*a1a3b679SAndreas Boehler                $parts = DateTimeParser::parseVCardDateTime($property->getValue());
172*a1a3b679SAndreas Boehler                if ($parts['year']===$property['X-APPLE-OMIT-YEAR']->getValue()) {
173*a1a3b679SAndreas Boehler                    $newValue = '--' . $parts['month'] . '-' . $parts['date'];
174*a1a3b679SAndreas Boehler                    $newProperty->setValue($newValue);
175*a1a3b679SAndreas Boehler                }
176*a1a3b679SAndreas Boehler
177*a1a3b679SAndreas Boehler                // Regardless if the year matched or not, we do need to strip
178*a1a3b679SAndreas Boehler                // X-APPLE-OMIT-YEAR.
179*a1a3b679SAndreas Boehler                unset($parameters['X-APPLE-OMIT-YEAR']);
180*a1a3b679SAndreas Boehler
181*a1a3b679SAndreas Boehler            }
182*a1a3b679SAndreas Boehler            switch($property->name) {
183*a1a3b679SAndreas Boehler                case 'X-ABSHOWAS' :
184*a1a3b679SAndreas Boehler                    if (strtoupper($property->getValue()) === 'COMPANY') {
185*a1a3b679SAndreas Boehler                        $newProperty = $output->createProperty('KIND','ORG');
186*a1a3b679SAndreas Boehler                    }
187*a1a3b679SAndreas Boehler                    break;
188*a1a3b679SAndreas Boehler                case 'X-ADDRESSBOOKSERVER-KIND' :
189*a1a3b679SAndreas Boehler                    if (strtoupper($property->getValue()) === 'GROUP') {
190*a1a3b679SAndreas Boehler                        $newProperty = $output->createProperty('KIND','GROUP');
191*a1a3b679SAndreas Boehler                    }
192*a1a3b679SAndreas Boehler                    break;
193*a1a3b679SAndreas Boehler                case 'X-ANNIVERSARY' :
194*a1a3b679SAndreas Boehler                    $newProperty->name = 'ANNIVERSARY';
195*a1a3b679SAndreas Boehler                    // If we already have an anniversary property with the same
196*a1a3b679SAndreas Boehler                    // value, ignore.
197*a1a3b679SAndreas Boehler                    foreach ($output->select('ANNIVERSARY') as $anniversary) {
198*a1a3b679SAndreas Boehler                        if ($anniversary->getValue() === $newProperty->getValue()) {
199*a1a3b679SAndreas Boehler                            return;
200*a1a3b679SAndreas Boehler                        }
201*a1a3b679SAndreas Boehler                    }
202*a1a3b679SAndreas Boehler                    break;
203*a1a3b679SAndreas Boehler                case 'X-ABDATE' :
204*a1a3b679SAndreas Boehler                    // Find out what the label was, if it exists.
205*a1a3b679SAndreas Boehler                    if (!$property->group) {
206*a1a3b679SAndreas Boehler                        break;
207*a1a3b679SAndreas Boehler                    }
208*a1a3b679SAndreas Boehler                    $label = $input->{$property->group . '.X-ABLABEL'};
209*a1a3b679SAndreas Boehler
210*a1a3b679SAndreas Boehler                    // We only support converting anniversaries.
211*a1a3b679SAndreas Boehler                    if (!$label || $label->getValue()!=='_$!<Anniversary>!$_') {
212*a1a3b679SAndreas Boehler                        break;
213*a1a3b679SAndreas Boehler                    }
214*a1a3b679SAndreas Boehler
215*a1a3b679SAndreas Boehler                    // If we already have an anniversary property with the same
216*a1a3b679SAndreas Boehler                    // value, ignore.
217*a1a3b679SAndreas Boehler                    foreach ($output->select('ANNIVERSARY') as $anniversary) {
218*a1a3b679SAndreas Boehler                        if ($anniversary->getValue() === $newProperty->getValue()) {
219*a1a3b679SAndreas Boehler                            return;
220*a1a3b679SAndreas Boehler                        }
221*a1a3b679SAndreas Boehler                    }
222*a1a3b679SAndreas Boehler                    $newProperty->name = 'ANNIVERSARY';
223*a1a3b679SAndreas Boehler                    break;
224*a1a3b679SAndreas Boehler                // Apple's per-property label system.
225*a1a3b679SAndreas Boehler                case 'X-ABLABEL' :
226*a1a3b679SAndreas Boehler                    if($newProperty->getValue() === '_$!<Anniversary>!$_') {
227*a1a3b679SAndreas Boehler                        // We can safely remove these, as they are converted to
228*a1a3b679SAndreas Boehler                        // ANNIVERSARY properties.
229*a1a3b679SAndreas Boehler                        return;
230*a1a3b679SAndreas Boehler                    }
231*a1a3b679SAndreas Boehler                    break;
232*a1a3b679SAndreas Boehler
233*a1a3b679SAndreas Boehler            }
234*a1a3b679SAndreas Boehler
235*a1a3b679SAndreas Boehler        }
236*a1a3b679SAndreas Boehler
237*a1a3b679SAndreas Boehler        // set property group
238*a1a3b679SAndreas Boehler        $newProperty->group = $property->group;
239*a1a3b679SAndreas Boehler
240*a1a3b679SAndreas Boehler        if ($targetVersion===Document::VCARD40) {
241*a1a3b679SAndreas Boehler            $this->convertParameters40($newProperty, $parameters);
242*a1a3b679SAndreas Boehler        } else {
243*a1a3b679SAndreas Boehler            $this->convertParameters30($newProperty, $parameters);
244*a1a3b679SAndreas Boehler        }
245*a1a3b679SAndreas Boehler
246*a1a3b679SAndreas Boehler        // Lastly, we need to see if there's a need for a VALUE parameter.
247*a1a3b679SAndreas Boehler        //
248*a1a3b679SAndreas Boehler        // We can do that by instantating a empty property with that name, and
249*a1a3b679SAndreas Boehler        // seeing if the default valueType is identical to the current one.
250*a1a3b679SAndreas Boehler        $tempProperty = $output->createProperty($newProperty->name);
251*a1a3b679SAndreas Boehler        if ($tempProperty->getValueType() !== $newProperty->getValueType()) {
252*a1a3b679SAndreas Boehler            $newProperty['VALUE'] = $newProperty->getValueType();
253*a1a3b679SAndreas Boehler        }
254*a1a3b679SAndreas Boehler
255*a1a3b679SAndreas Boehler        $output->add($newProperty);
256*a1a3b679SAndreas Boehler
257*a1a3b679SAndreas Boehler
258*a1a3b679SAndreas Boehler    }
259*a1a3b679SAndreas Boehler
260*a1a3b679SAndreas Boehler    /**
261*a1a3b679SAndreas Boehler     * Converts a BINARY property to a URI property.
262*a1a3b679SAndreas Boehler     *
263*a1a3b679SAndreas Boehler     * vCard 4.0 no longer supports BINARY properties.
264*a1a3b679SAndreas Boehler     *
265*a1a3b679SAndreas Boehler     * @param Component\VCard $output
266*a1a3b679SAndreas Boehler     * @param Property\Uri $property The input property.
267*a1a3b679SAndreas Boehler     * @param $parameters List of parameters that will eventually be added to
268*a1a3b679SAndreas Boehler     *                    the new property.
269*a1a3b679SAndreas Boehler     * @return Property\Uri
270*a1a3b679SAndreas Boehler     */
271*a1a3b679SAndreas Boehler    protected function convertBinaryToUri(Component\VCard $output, Property\Binary $newProperty, array &$parameters) {
272*a1a3b679SAndreas Boehler
273*a1a3b679SAndreas Boehler        $value = $newProperty->getValue();
274*a1a3b679SAndreas Boehler        $newProperty = $output->createProperty(
275*a1a3b679SAndreas Boehler            $newProperty->name,
276*a1a3b679SAndreas Boehler            null, // no value
277*a1a3b679SAndreas Boehler            array(), // no parameters yet
278*a1a3b679SAndreas Boehler            'URI' // Forcing the BINARY type
279*a1a3b679SAndreas Boehler        );
280*a1a3b679SAndreas Boehler
281*a1a3b679SAndreas Boehler        $mimeType = 'application/octet-stream';
282*a1a3b679SAndreas Boehler
283*a1a3b679SAndreas Boehler        // See if we can find a better mimetype.
284*a1a3b679SAndreas Boehler        if (isset($parameters['TYPE'])) {
285*a1a3b679SAndreas Boehler
286*a1a3b679SAndreas Boehler            $newTypes = array();
287*a1a3b679SAndreas Boehler            foreach($parameters['TYPE']->getParts() as $typePart) {
288*a1a3b679SAndreas Boehler                if (in_array(
289*a1a3b679SAndreas Boehler                    strtoupper($typePart),
290*a1a3b679SAndreas Boehler                    array('JPEG','PNG','GIF')
291*a1a3b679SAndreas Boehler                )) {
292*a1a3b679SAndreas Boehler                    $mimeType = 'image/' . strtolower($typePart);
293*a1a3b679SAndreas Boehler                } else {
294*a1a3b679SAndreas Boehler                    $newTypes[] = $typePart;
295*a1a3b679SAndreas Boehler                }
296*a1a3b679SAndreas Boehler            }
297*a1a3b679SAndreas Boehler
298*a1a3b679SAndreas Boehler            // If there were any parameters we're not converting to a
299*a1a3b679SAndreas Boehler            // mime-type, we need to keep them.
300*a1a3b679SAndreas Boehler            if ($newTypes) {
301*a1a3b679SAndreas Boehler                $parameters['TYPE']->setParts($newTypes);
302*a1a3b679SAndreas Boehler            } else {
303*a1a3b679SAndreas Boehler                unset($parameters['TYPE']);
304*a1a3b679SAndreas Boehler            }
305*a1a3b679SAndreas Boehler
306*a1a3b679SAndreas Boehler        }
307*a1a3b679SAndreas Boehler
308*a1a3b679SAndreas Boehler        $newProperty->setValue('data:' . $mimeType . ';base64,' . base64_encode($value));
309*a1a3b679SAndreas Boehler        return $newProperty;
310*a1a3b679SAndreas Boehler
311*a1a3b679SAndreas Boehler    }
312*a1a3b679SAndreas Boehler
313*a1a3b679SAndreas Boehler    /**
314*a1a3b679SAndreas Boehler     * Converts a URI property to a BINARY property.
315*a1a3b679SAndreas Boehler     *
316*a1a3b679SAndreas Boehler     * In vCard 4.0 attachments are encoded as data: uri. Even though these may
317*a1a3b679SAndreas Boehler     * be valid in vCard 3.0 as well, we should convert those to BINARY if
318*a1a3b679SAndreas Boehler     * possible, to improve compatibility.
319*a1a3b679SAndreas Boehler     *
320*a1a3b679SAndreas Boehler     * @param Component\VCard $output
321*a1a3b679SAndreas Boehler     * @param Property\Uri $property The input property.
322*a1a3b679SAndreas Boehler     * @return Property\Binary|null
323*a1a3b679SAndreas Boehler     */
324*a1a3b679SAndreas Boehler    protected function convertUriToBinary(Component\VCard $output, Property\Uri $newProperty) {
325*a1a3b679SAndreas Boehler
326*a1a3b679SAndreas Boehler        $value = $newProperty->getValue();
327*a1a3b679SAndreas Boehler
328*a1a3b679SAndreas Boehler        // Only converting data: uris
329*a1a3b679SAndreas Boehler        if (substr($value, 0, 5)!=='data:') {
330*a1a3b679SAndreas Boehler            return $newProperty;
331*a1a3b679SAndreas Boehler        }
332*a1a3b679SAndreas Boehler
333*a1a3b679SAndreas Boehler        $newProperty = $output->createProperty(
334*a1a3b679SAndreas Boehler            $newProperty->name,
335*a1a3b679SAndreas Boehler            null, // no value
336*a1a3b679SAndreas Boehler            array(), // no parameters yet
337*a1a3b679SAndreas Boehler            'BINARY'
338*a1a3b679SAndreas Boehler        );
339*a1a3b679SAndreas Boehler
340*a1a3b679SAndreas Boehler        $mimeType = substr($value, 5, strpos($value, ',')-5);
341*a1a3b679SAndreas Boehler        if (strpos($mimeType, ';')) {
342*a1a3b679SAndreas Boehler            $mimeType = substr($mimeType,0,strpos($mimeType, ';'));
343*a1a3b679SAndreas Boehler            $newProperty->setValue(base64_decode(substr($value, strpos($value,',')+1)));
344*a1a3b679SAndreas Boehler        } else {
345*a1a3b679SAndreas Boehler            $newProperty->setValue(substr($value, strpos($value,',')+1));
346*a1a3b679SAndreas Boehler        }
347*a1a3b679SAndreas Boehler        unset($value);
348*a1a3b679SAndreas Boehler
349*a1a3b679SAndreas Boehler        $newProperty['ENCODING'] = 'b';
350*a1a3b679SAndreas Boehler        switch($mimeType) {
351*a1a3b679SAndreas Boehler
352*a1a3b679SAndreas Boehler            case 'image/jpeg' :
353*a1a3b679SAndreas Boehler                $newProperty['TYPE'] = 'JPEG';
354*a1a3b679SAndreas Boehler                break;
355*a1a3b679SAndreas Boehler            case 'image/png' :
356*a1a3b679SAndreas Boehler                $newProperty['TYPE'] = 'PNG';
357*a1a3b679SAndreas Boehler                break;
358*a1a3b679SAndreas Boehler            case 'image/gif' :
359*a1a3b679SAndreas Boehler                $newProperty['TYPE'] = 'GIF';
360*a1a3b679SAndreas Boehler                break;
361*a1a3b679SAndreas Boehler
362*a1a3b679SAndreas Boehler        }
363*a1a3b679SAndreas Boehler
364*a1a3b679SAndreas Boehler
365*a1a3b679SAndreas Boehler        return $newProperty;
366*a1a3b679SAndreas Boehler
367*a1a3b679SAndreas Boehler    }
368*a1a3b679SAndreas Boehler
369*a1a3b679SAndreas Boehler    /**
370*a1a3b679SAndreas Boehler     * Adds parameters to a new property for vCard 4.0
371*a1a3b679SAndreas Boehler     *
372*a1a3b679SAndreas Boehler     * @param Property $newProperty
373*a1a3b679SAndreas Boehler     * @param array $parameters
374*a1a3b679SAndreas Boehler     * @return void
375*a1a3b679SAndreas Boehler     */
376*a1a3b679SAndreas Boehler    protected function convertParameters40(Property $newProperty, array $parameters) {
377*a1a3b679SAndreas Boehler
378*a1a3b679SAndreas Boehler        // Adding all parameters.
379*a1a3b679SAndreas Boehler        foreach($parameters as $param) {
380*a1a3b679SAndreas Boehler
381*a1a3b679SAndreas Boehler            // vCard 2.1 allowed parameters with no name
382*a1a3b679SAndreas Boehler            if ($param->noName) $param->noName = false;
383*a1a3b679SAndreas Boehler
384*a1a3b679SAndreas Boehler            switch($param->name) {
385*a1a3b679SAndreas Boehler
386*a1a3b679SAndreas Boehler                // We need to see if there's any TYPE=PREF, because in vCard 4
387*a1a3b679SAndreas Boehler                // that's now PREF=1.
388*a1a3b679SAndreas Boehler                case 'TYPE' :
389*a1a3b679SAndreas Boehler                    foreach($param->getParts() as $paramPart) {
390*a1a3b679SAndreas Boehler
391*a1a3b679SAndreas Boehler                        if (strtoupper($paramPart)==='PREF') {
392*a1a3b679SAndreas Boehler                            $newProperty->add('PREF','1');
393*a1a3b679SAndreas Boehler                        } else {
394*a1a3b679SAndreas Boehler                            $newProperty->add($param->name, $paramPart);
395*a1a3b679SAndreas Boehler                        }
396*a1a3b679SAndreas Boehler
397*a1a3b679SAndreas Boehler                    }
398*a1a3b679SAndreas Boehler                    break;
399*a1a3b679SAndreas Boehler                // These no longer exist in vCard 4
400*a1a3b679SAndreas Boehler                case 'ENCODING' :
401*a1a3b679SAndreas Boehler                case 'CHARSET' :
402*a1a3b679SAndreas Boehler                    break;
403*a1a3b679SAndreas Boehler
404*a1a3b679SAndreas Boehler                default :
405*a1a3b679SAndreas Boehler                    $newProperty->add($param->name, $param->getParts());
406*a1a3b679SAndreas Boehler                    break;
407*a1a3b679SAndreas Boehler
408*a1a3b679SAndreas Boehler            }
409*a1a3b679SAndreas Boehler
410*a1a3b679SAndreas Boehler        }
411*a1a3b679SAndreas Boehler
412*a1a3b679SAndreas Boehler    }
413*a1a3b679SAndreas Boehler
414*a1a3b679SAndreas Boehler    /**
415*a1a3b679SAndreas Boehler     * Adds parameters to a new property for vCard 3.0
416*a1a3b679SAndreas Boehler     *
417*a1a3b679SAndreas Boehler     * @param Property $newProperty
418*a1a3b679SAndreas Boehler     * @param array $parameters
419*a1a3b679SAndreas Boehler     * @return void
420*a1a3b679SAndreas Boehler     */
421*a1a3b679SAndreas Boehler    protected function convertParameters30(Property $newProperty, array $parameters) {
422*a1a3b679SAndreas Boehler
423*a1a3b679SAndreas Boehler        // Adding all parameters.
424*a1a3b679SAndreas Boehler        foreach($parameters as $param) {
425*a1a3b679SAndreas Boehler
426*a1a3b679SAndreas Boehler            // vCard 2.1 allowed parameters with no name
427*a1a3b679SAndreas Boehler            if ($param->noName) $param->noName = false;
428*a1a3b679SAndreas Boehler
429*a1a3b679SAndreas Boehler            switch($param->name) {
430*a1a3b679SAndreas Boehler
431*a1a3b679SAndreas Boehler                case 'ENCODING' :
432*a1a3b679SAndreas Boehler                    // This value only existed in vCard 2.1, and should be
433*a1a3b679SAndreas Boehler                    // removed for anything else.
434*a1a3b679SAndreas Boehler                    if (strtoupper($param->getValue())!=='QUOTED-PRINTABLE') {
435*a1a3b679SAndreas Boehler                        $newProperty->add($param->name, $param->getParts());
436*a1a3b679SAndreas Boehler                    }
437*a1a3b679SAndreas Boehler                    break;
438*a1a3b679SAndreas Boehler
439*a1a3b679SAndreas Boehler                /*
440*a1a3b679SAndreas Boehler                 * Converting PREF=1 to TYPE=PREF.
441*a1a3b679SAndreas Boehler                 *
442*a1a3b679SAndreas Boehler                 * Any other PREF numbers we'll drop.
443*a1a3b679SAndreas Boehler                 */
444*a1a3b679SAndreas Boehler                case 'PREF' :
445*a1a3b679SAndreas Boehler                    if ($param->getValue()=='1') {
446*a1a3b679SAndreas Boehler                        $newProperty->add('TYPE','PREF');
447*a1a3b679SAndreas Boehler                    }
448*a1a3b679SAndreas Boehler                    break;
449*a1a3b679SAndreas Boehler
450*a1a3b679SAndreas Boehler                default :
451*a1a3b679SAndreas Boehler                    $newProperty->add($param->name, $param->getParts());
452*a1a3b679SAndreas Boehler                    break;
453*a1a3b679SAndreas Boehler
454*a1a3b679SAndreas Boehler            }
455*a1a3b679SAndreas Boehler
456*a1a3b679SAndreas Boehler        }
457*a1a3b679SAndreas Boehler
458*a1a3b679SAndreas Boehler    }
459*a1a3b679SAndreas Boehler}
460